Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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:

  1. Since the call site of getA is in global scope, getA() will be bound to global object.
  2. 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.
  3. Because of that, I expect this.a to refer to variable a.
  4. 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 alerts the string foo, just as expected.

Why does the output of Chrome differ from Node.js?

like image 668
sampathsris Avatar asked Nov 20 '14 04:11

sampathsris


People also ask

Do NodeJS and Chrome have the same JavaScript interpreter?

Node uses the same JS "engine" that runs chrome. An engine in this case, is a piece of software that compiles, or "translates" your JS code into machine code; or the 0s and 1s your computer can understand.

What is the difference between browser and NodeJS?

Another difference is that Node. js supports both the CommonJS and ES module systems (since Node. js v12), while in the browser we are starting to see the ES Modules standard being implemented. In practice, this means that you can use both require() and import in Node.

What is default binding in JavaScript?

Default binding refers to how this is the global context whenever a function is invoked without any of these other rules. If we aren't using a dot and we aren't using call(), apply(), or bind(), our this will be our global object. Your global context depends on where you're working.

Does NodeJS work on Chrome?

The V8 engine is what powers Node. js and it is an open-source engine on which even Chrome works. It parses and runs your JavaScript inside a Node environment.


1 Answers

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

This is a misunderstanding of the this binding rules from my book. The call site's location (aka "in global scope") is entirely irrelevant. It's the manner in which the call is made, and only that.

It's not where getA() happens that matters, but that getA() is a plain normal function call. THAT is what determines that you'll get the global object bound to the this for that call.

The other answers here are correct... the scope your node main program runs in is actually a module (function wrapped), not a real global scope.

like image 187
Kyle Simpson Avatar answered Sep 18 '22 15:09

Kyle Simpson