javascript - 为什么 JavaScript "this"在 Node 和 Browser 环境中返回不同的值?

标签 javascript node.js function binding this

看完凯尔·辛普森的 Advanced JavaScript在 Pluralsight 类(class)中,我创建了一个简单的代码片段来尝试 this 绑定(bind)。我通常在 SublimeText 编辑器中工作,并在其中配置了 Node 构建引擎,偶尔我也会在浏览器中运行相同的代码。我注意到在 Node 和浏览器 [Chrome] 中执行代码时程序输出存在一个差异。

以下是尝试 this 绑定(bind)的代码片段。

function foo() {
    console.log(this.bar);
}

var bar = "bar1";
var obj = {bar : "bar2"};

foo();
foo.call(obj);

当我使用 Sublime 执行它时,它返回 undefinedbar2。但是,当我在浏览器中执行相同的代码段时,它返回 bar1bar2,我认为这是正确的,因为变量 bar 是在全局范围内定义的。我无法理解为什么 Node 环境将其返回为 undefined。请帮忙。

最佳答案

在 node.js 中,您的 bar 变量是该模块的本地模块变量。它不是全局变量。 Node 中的全局变量必须显式分配给 global 对象。 node.js 模块中的顶级声明不会像在浏览器 JS 文件中那样自动成为全局变量。从技术上讲,它们存在于由模块加载器创建的函数范围内,因此它们是模块函数范围的局部变量。

在 node.js 中,像 foo() 这样的普通函数调用中 this 的值是 global 对象。

但是,在 node.js 中,您的 bar 变量不是全局对象的属性。因此,当您尝试引用 this.bar 时,它是 global.bar 并且全局对象上没有该名称的属性。

因此,在 node.js 中,您基本上是这样做的:

// create a function which is like the module scope
function myModuleFunc() {
    function foo() {
        // the value of this in a plain function call in node.js is the
        // global object
        console.log(global.bar);
    }

    // this isn't a global
    var bar = "bar1";

    foo();
}

// execute that module scope function
myModuleFunction();

而且,希望您能明白为什么没有 global.bar 属性,因此您会得到 undefined


这一切都意外地在浏览器中工作,因为 var bar 是一个全局变量,而全局变量在 window 对象和 this === window 上所以它不小心起作用了。两个错误构成一个正确,但有时会奏效。

正如我在评论中所说,强烈建议在严格模式下运行您的代码,有时不会意外工作,但其他情况不会 - 这个问题将高度一致,当您有写错了代码。


虽然您说您已经了解浏览器环境中发生的情况,但由于您的问题是问为什么两者不同,所以我将描述浏览器情况以涵盖所有基础。

在浏览器中,this 在普通函数调用中的值(当不在严格模式下时)是 window 对象。

在浏览器中,您的 bar 变量是一个全局变量,因此自动成为 window 对象的属性。

因此,在浏览器中,您基本上是这样做的:

function foo() {
    console.log(window.bar);
}

window.bar = "bar1";

foo();

因此,您可以看到为什么它会愉快地在 window 对象上创建一个属性,然后引用它。

关于javascript - 为什么 JavaScript "this"在 Node 和 Browser 环境中返回不同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31261058/

相关文章:

Javascript 如果数组包含带有正则表达式的字符串

node.js - 仅使用 websockets 构建整个站点(通过 socket.io 和 node.js,没有 Ajax)?

c# - 使用对象发送者和 EventArgs 调用方法 c#

javascript - 使用 jquery 增加和减少输入值

javascript - 从 jquery 中的按钮调用模态对话框表单

javascript - 如何将类属性传递给嵌套在 NodeJS 中 class>method>each 内的 .each block ?

javascript - 你如何让axios GET请求等待?

php - 调用未定义函数 str_getcsv()

python - 提取字典字段用作函数名称

javascript - Node.js/变量和模块的继承