为什么JavaScript“this”在节点和浏览器环境中返回不同的值? [英] Why does JavaScript "this" returns different values in Node and Browser environments?

查看:172
本文介绍了为什么JavaScript“this”在节点和浏览器环境中返回不同的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在观看了Kyle Simpson关于Pluralsight的高级JavaScript 课程后,我创建了一个简单的代码片段尝试这个绑定。我通常在SublimeText编辑器中工作,并在其中配置了节点构建引擎,偶尔我也会在浏览器中运行相同的代码。我在Node和Browser [Chrome]中执行代码时注意到了程序输出的一个区别。



以下是测试的代码片段,这个绑定。

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

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

foo();
foo.call(obj);

当我使用Sublime执行它时,它返回 undefined bar2 。然而,当我在浏览器中执行相同的片段时,它会返回 bar1 bar2 ,我认为这是正确的,因为变量 bar 在全局范围内定义。我无法理解为什么Node环境将它作为 undefined 返回。请帮助。

解决方案

在node.js中,您的 bar 变量是一个模块变量,该模块是本地的。这不是一个全局变量。全局节点必须明确分配给<​​code>全局对象。 node.js模块中的顶层声明并非像浏览器JS文件中那样是全局的。从技术上讲,它们存在于由模块加载器创建的函数范围内,因此它们是模块函数范围的局部变量。



在node.js中, code>这个是一个普通的函数调用,如 foo()全局 object。



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



所以,在node.js中,你基本上是这么做的:

  //创建一个类似于模块范围的函数
函数myModuleFunc(){
函数foo(){
//这是一个普通函数的值在node.js中调用的是
//全局对象
console.log(global.bar);
}

//这不是全局的
var bar =bar1;

foo();
}

//执行该模块范围函数
myModuleFunction();

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






这一切都意外地在浏览器中工作,因为 var bar 是全局的,全局变量位于窗口对象和这个===窗口所以它意外的工作。正如我在我的评论中所说的那样,强烈建议您在严格模式下运行您的代码,并且事情有时不会意外地工作,但不是其他人 - 这个问题将会是高度一致的,当你写错了代码的时候你会立即发现错误。






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



在浏览器中,普通函数调用(非严格模式下)中 this 的值是窗口 object。



在浏览器中, bar 变量是一个全局变量,成为窗口对象的属性。

所以,在浏览器中,你基本上是这样做的: p>

 函数fo o(){
console.log(window.bar);
}

window.bar =bar1;

foo();

然后,您可以看到为什么它很乐意在窗口中创建一个属性对象,然后引用它。


After watching Kyle Simpson's Advanced JavaScript course on Pluralsight, I created a simple code snippet to try out this binding. I usually work in SublimeText editor and have node build engine configured in it and occasionally I run the same code in browser as well. I have noticed one difference in the program output when execute code in Node and in Browser [Chrome].

Following is the code snippet to try out this binding.

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

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

foo();
foo.call(obj);

When I execute it using Sublime, it returns undefined and bar2. However when I execute same snippet in a browser it returns bar1 and bar2, which I think is correct since variable bar is defined at global scope. I am not able to understand why Node environment is returning it as undefined. Kindly help.

解决方案

In node.js, your bar variable is a module variable which is local to that module. It is not a global variable. Globals in node must be explicitly assigned to the global object. Top level declarations in a node.js module are not automatically globals like they are in a browser JS file. Technically, they exist inside a function scope that is created by the module loader so they are local variables to the module's function scope.

In node.js, the value of this in a plain function call like foo() is the global object.

But, in node.js, your bar variable is NOT a property of the global object. So, when you try to reference this.bar, that's global.bar and there is no property on the global object by that name.

So, in node.js, you're essentially doing this:

// 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();

And, hopefully you can see why there is no global.bar property, thus you get undefined.


This all accidentally works in a browser because var bar is a global and globals are on the window object and this === window so it accidentally works. Two wrongs make a right that works only sometimes.

As I said in my comment, it is highly recommended to run your code in strict mode and things will not accidentally work sometimes, but not others - this issue will all be highly consistent and you will get an immediate error when you have written the wrong sort of code.


Though you said you already understand what is happening in the browser environment, since your question asks why the two are different, I will describe the browser situation just to cover all the bases.

In the browser, the value of this in a plain function call (when not in strict mode) is the window object.

In the browser, your bar variable is a global variable and thus automatically becomes a property of the window object.

So, in the browser, you are essentially doing this:

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

window.bar = "bar1";

foo();

And, thus you can see why it happily creates a property on the window object and then references it.

这篇关于为什么JavaScript“this”在节点和浏览器环境中返回不同的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆