Javascript node.js中的全局作用域与浏览器中的全局作用域有何不同(有具体示例)?
我遇到了凯尔·辛普森(Kyle Simpson)关于这个和对象原型的优秀的“你不知道JS”书的问题 如果您想阅读关于发生了什么的完整上下文,本书的文本将包含在GitHub链接中 下面是有问题的代码:Javascript node.js中的全局作用域与浏览器中的全局作用域有何不同(有具体示例)?,javascript,node.js,Javascript,Node.js,我遇到了凯尔·辛普森(Kyle Simpson)关于这个和对象原型的优秀的“你不知道JS”书的问题 如果您想阅读关于发生了什么的完整上下文,本书的文本将包含在GitHub链接中 下面是有问题的代码: if (!Function.prototype.softBind) { Function.prototype.softBind = function(obj) { var fn = this, curried = [].slice.call( arguments, 1 )
if (!Function.prototype.softBind) {
Function.prototype.softBind = function(obj) {
var fn = this,
curried = [].slice.call( arguments, 1 ),
bound = function bound() {
if (this === global) {console.log('this is global')}
console.log(this);
return fn.apply(
(!this ||
(typeof window !== "undefined" &&
this === window) ||
(typeof global !== "undefined" &&
this === global)
) ? obj : this,
curried.concat.apply( curried, arguments )
);
};
bound.prototype = Object.create( fn.prototype );
return bound;
};
}
function foo() {
console.log("name: " + this.name);
}
var obj = { name: 'obj'};
var obj2 = { name: 'obj2'};
var obj3 = { name: 'obj3'};
var fooOBJ = foo.softBind(obj);
fooOBJ(); // name: obj
obj2.foo = foo.softBind(obj);
obj2.foo(); // name: obj2
fooOBJ.call(obj3); // name: obj3
setTimeout(obj2.foo, 10); // name: obj (only in browser, name: undefined if in node)
出于这个问题的目的,我只对最后一行代码的输出感兴趣,正如注释所示,在浏览器中打印“name:obj”,但在节点中打印“name:undefined”
有人能解释一下这种差异的原因吗?是否可以对softBind函数进行更改,从而使代码在两种环境中都能正常工作 如您在
绑定
中记录this
的值所见,当函数被称为设置超时
回调时,此
被设置为一个特殊的超时对象:
{ _idleTimeout: 10,
_idlePrev: null,
_idleNext: null,
_idleStart: 1417462313179,
_monotonicStartTime: 36214497,
_onTimeout: [Function: bound],
_repeat: false }
也就是说,与浏览器中的setTimeout
不同,它不引用全局对象。这就是为什么
(typeof global !== "undefined" && this === global)
未实现,并且
foo
的设置为超时对象,而不是obj
如您在绑定
中记录this
的值所见,当函数被称为设置超时
回调时,此
被设置为一个特殊的超时对象:
{ _idleTimeout: 10,
_idlePrev: null,
_idleNext: null,
_idleStart: 1417462313179,
_monotonicStartTime: 36214497,
_onTimeout: [Function: bound],
_repeat: false }
也就是说,与浏览器中的setTimeout
不同,它不引用全局对象。这就是为什么
(typeof global !== "undefined" && this === global)
未实现,并且foo
的设置为超时对象,而不是obj
运行节点v0.10.26运行节点v0.10.26正常,但节点为什么要这样做?谢谢你的回答,但我只是想知道为什么这种行为与Chrome或Firefox中的行为不同。我不能给你一个明确的答案,但请记住,setTimeout
不是ECMAScript规范的一部分。它是由浏览器提供的,只是最近才正式成为HTML5的一部分。但是,本规范并未规定此
应参考的内容。实际上,this
引用全局对象的事实被视为不利因素,这就是为什么在严格模式下禁用此行为的原因。这不是我所希望的启示,而是提供了澄清。非常感谢你!澄清:HTML规范实际上规定了由setTimeout(…)
调用的函数中的this
应该始终是全局的。所有浏览器都会/应该遵守这一点。但是,节点不受HTML规范的约束,因此允许并且确实有自己的setTimeout(..)
实现,其工作方式不同,如上所述:/好的,但是node为什么要这样做呢?谢谢你的回答,但我只是想知道为什么这种行为与Chrome或Firefox中的行为不同。我不能给你一个明确的答案,但请记住,setTimeout
不是ECMAScript规范的一部分。它是由浏览器提供的,只是最近才正式成为HTML5的一部分。但是,本规范并未规定此
应参考的内容。实际上,this
引用全局对象的事实被视为不利因素,这就是为什么在严格模式下禁用此行为的原因。这不是我所希望的启示,而是提供了澄清。非常感谢你!澄清:HTML规范实际上规定了由setTimeout(…)
调用的函数中的this
应该始终是全局的。所有浏览器都会/应该遵守这一点。但是,节点不受HTML规范的约束,因此允许并且确实有自己的setTimeout(..)
实现,其工作方式不同,如上所述:/