The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

ptmy (22) [Avatar] Offline
#1
I just finished reading the revised chapters 1 to 5. The new content is much more informative than before. I really like how the authors handle the ES6 additions. Everything's clearly explained - excellent writing.

However, I do have a couple of questions not answered in the book (or maybe I just missed the answers, or haven't gotten to it yet). These are as follows:

1) What's the value of the 'this' pointer inside a callback function of a function called as an object's method? For example, using the code shown below, what's the value of 'this' inside the callback function for 'setTimeout'? Lines 26 to 34 show results when run using node.js. Results shown in lines 26 to 31 are what I expected based on explanations in the book. I read in some forums saying the 'global' object in nodejs is equivalent to the 'window' object in the browser. I thought 'this' inside the setTimerout function would equal 'global'. But it doesn't.

2) A related question pertaining to the event loop: if the 'delay()' function shown below happens to be the callback function for a click event in the browser, when does the callback function inside 'setTimeout' get put into the event queue?


[color=blue]
function whatsMyContext() {
    console.log ('this equals global in whatsMyContext? ' + (this===global));
    console.log ('this equals n1 in whatsMyContext? ' + (this===n1));
}

function delay(){
	console.log ('this equals n1 in function delay: ' + (this===n1));
	setTimeout(function() {
		console.log ('this equals n1 in setTimeout callback: ' + (this===n1));
		console.log ('this equals global in setTimeout callback: ' + (this===global));
		console.log ('this equals process in setTimeout callback: ' + (this===process));
		console.log ('this equals undefined in setTimeout callback: ' + (this===undefined));
	}, 3000);
};

var n1 = {
	getMyContext: whatsMyContext,
	delayContext: delay
};

whatsMyContext();
n1.getMyContext();
n1.delayContext();[/color]


this equals global in whatsMyContext? true
this equals n1 in whatsMyContext? false
this equals global in whatsMyContext? false
this equals n1 in whatsMyContext? true
this equals n1 in function delay: true
this equals n1 in setTimeout callback: false
this equals global in setTimeout callback: false
this equals process in setTimeout callback: false
this equals undefined in setTimeout callback: false
Josip Maras (30) [Avatar] Offline
#2
Hi,

1) What's the value of the 'this' pointer inside a callback function of a function called as an object's method?


This depends on how the callback was defined (is it an arrow function, a bound function, or a "normal" function) and what calls the callback.

In your case, since it is a setTimeout callback and the function is a standard one, the value of the this parameter should be equal to the global object (if the code is executed in a browser, the window object). You can verify this by running your code in jsbin: http://jsbin.com/fokujafage/edit?js,console.

However, as you point out, things are a bit different in node. While I'm far from an expert in node, it seems that in node when you call the setTimeout function ((https://nodejs.org/api/timers.html#timers_settimeout_callback_delay_arg)), node returns an object (while a browser returns a simple id through which you can cancel the timer), and that object is used as the context (the this value) of the setTimeout callback (instead of the global object).

You can test this by slightly modifying your code:

var timerResult = setTimeout(function() {
  console.log ('this equals n1 in setTimeout callback: ' + (this===n1));
  console.log ('this equals global in setTimeout callback: ' + (this===global));
  console.log ('this equals process in setTimeout callback: ' + (this===process));
  console.log ('this equals undefined in setTimeout callback: ' + (this===undefined));
  console.log ('this equals timerResult in setTimeout callback: ' + (this===timerResult));//evaluates to true
}, 3000);


2) A related question pertaining to the event loop: if the 'delay()' function shown below happens to be the callback function for a click event in the browser, when does the callback function inside 'setTimeout' get put into the event queue?


In your case, the setTimeout callback will be placed in the event queue roughly 3 seconds after the click handler gets executed.

Actually, the next MEAP of the book contains a chapter called: "Surviving events" where we go into great detail about how the event loop works (with a special focus on timers).

Josip