sam*_*ris 8 javascript scope google-chrome v8 node.js
我正在阅读第2章:this所有人现在都有意义!来自你不了解JS,并决定做这个实验.
我有这个简单的脚本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);
Run Code Online (Sandbox Code Playgroud)
我期待以下事情getA()被称为:
getA在全局范围内,getA()将绑定到全局对象.var a在全局范围内声明,我认为全局对象将具有一个名为的属性a,并且此属性与变量相同a.this.a引用变量a.output(foo)打印字符串foo.但是,在Node.js(非严格模式)下运行时,这是输出:
$ node foo.js
undefined
Run Code Online (Sandbox Code Playgroud)
然后我在一个简单的HTML页面中包含了相同的脚本,并将其加载到chrome中.
<html>
<head>
<script src="foo.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,Chrome alert是字符串foo.
为什么Chrome的输出与Node.js不同?
Kyl*_*son 14
由于getA的调用站点在全局范围内,因此getA()将绑定到全局对象.
这是对this我书中约束规则的误解.呼叫站点的位置(又名"在全球范围内")完全无关紧要.这是进行呼叫的方式,而且仅限于此.
它不是重要的地方 getA(),但这getA()是一个普通的正常函数调用.THAT是什么决定了你会得到绑定到全局对象this的这一呼吁.
这里的其他答案是正确的......您的节点主程序运行的范围实际上是一个模块(函数包装),而不是真正的全局范围.
由于getA的调用站点在全局范围内,因此getA()将绑定到全局对象.
不,这不适用于节点 - 你的脚本被包装到一个函数中,所以你的例子实际上就是这个代码:
(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');
Run Code Online (Sandbox Code Playgroud)
小智 8
NodeJS的行为与浏览器不同.顶级范围不是全局范围,它是该文件或模块中的范围.删除"var",你的代码将在节点环境中工作(一个将成为真正的全局),它将console.log字符串'foo'.
有关完整参考,请参阅以下页面:http://nodejs.org/api/globals.html
要么