Default binding of `this` is different from Chrome browser and Node.js

google-chrome, javascript, node.js, scope, v8

Solution

Since the call site of getA is in global scope, getA() will be bound to global object.

no, that's not true for node - your script is wrapped into a function here so your example is actually this code:

(function (exports, require, module, __filename, __dirname) {
  var a = 'foo';
  var output;

  // lets find a way to output strings in both
  // Chrome and Node.js
  if (typeof alert === 'undefined') {
    output = console.log;
  } else {
    output = alert;
  }

  function getA() {
    return this.a;
  }

  var foo = getA();
  output(foo);
})(exports, require, module, 'file.js', '/dir/name');

Problem

I was reading Chapter 2: `this` All Makes Sense Now! from You Don't Know JS, and decided to do this experiment. I have this simple enough script `foo.js`: ``` var a = 'foo'; var output; // lets find a way to output strings in both // Chrome and Node.js if (typeof alert === 'undefined') { output = console.log; } else { output = alert; } function getA() { return this.a; } var foo = getA(); output(foo); ``` I am expecting following things when `getA()` is called: - Since the call site of `getA` is in global scope, `getA()` will be bound to global object. - Since `var a` is declared in global scope, I take it that global object will have a property named `a`, and this property is same as the variable `a`. - Because of that, I expect `this.a` to refer to variable `a`. - Thus I expect `output(foo)` to print the string `foo`. However, when run in Node.js (non-strict mode), this is the output: ``` $ node foo.js undefined ``` Then I included the same script in a simple HTML page, and loaded it in chrome. ``` <html> <head> <script src="foo.js" type="text/javascript"></script> </head> <body> </body> </html> ``` Chrome `alert`s the string `foo`, just as expected. Why does the output of Chrome differ from Node.js?

Original source

Related problems