Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

different behavior of keyword "this" between node.js and browsers

I've tried following code in ie, firefox and node.js

var x = 10;
var o = { x: 15 };
function f(){
     console.log(this.x);
}
f();
f.call(o);

the results in browsers are 10, 15, but the result in node.js is undefined, 15.

Please explain to me what is the different behavior of “this” keyword in browsers and node.js? I've read many pages but there wasn't any obvious answer. Thanks in advance.

like image 278
Cong Nguyen Avatar asked Dec 15 '12 19:12

Cong Nguyen


2 Answers

Javascript files loaded in Nodejs are automatically wrapped in anonymous functions.

So in Node what you are really running is:

(function(/* There are args here, but they aren't important for this answer */){
  var x = 10;
  var o = { x: 15 };
  function f(){
    console.log(this.x);
  }
  f();
  f.call(o);
})();

The browser does not do this. The issue is that now in Node x is just a normal variable in the scope of the function, it is not part of the global scope. When you call f() this way, this within f is the global scope.

If directly put x on the global scope, it will work in both cases.

this.x = 10;

That will place x on the window global object in the browser, and the global global object in Node.

Generally, you do not load things globally in Node, instead you group your code into modules, as described here. There is info about the various global things you can access here. And if you are curious about the wrapper, you can see it here.

like image 69
loganfsmyth Avatar answered Sep 22 '22 15:09

loganfsmyth


When calling a regular function as in f(), the behavior is different in strict mode vs. regular mode. In regular mode, this will be the global object (e.g. window). In strict mode, this will be undefined.

Other than that difference, the assignment of this in a function call is fully specified in the javascript standard so if you are seeing differences in different situations, then it is probably because of strict mode. Add strict mode to both environments and you should see consistent behavior.

You can read the section "Securing Javascript" at this MDN reference for more info.

like image 36
jfriend00 Avatar answered Sep 26 '22 15:09

jfriend00