最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Default binding of `this` is different from Chrome browser and Node.js - Stack Overflow

programmeradmin6浏览0评论

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?

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?

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Nov 20, 2014 at 4:16 sampathsrissampathsris 22.3k12 gold badges72 silver badges101 bronze badges 0
Add a comment  | 

3 Answers 3

Reset to default 15

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.

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');

NodeJS behaves differently than browsers. The top-level scope is not the global scope, it's the scope within that file or module. Drop the "var" and your code will work (a will become truly global) in a node environment and it will console.log the string 'foo'.

See the following page for a full reference: http://nodejs.org/api/globals.html

OR

How to use global variable in node.js?

发布评论

评论列表(0)

  1. 暂无评论