我在使用 Kyle Simpson 的关于此和对象原型(prototype)的优秀书籍“你不懂 JS”时遇到了问题。
如果您想了解有关正在发生的事情的完整上下文,则 GitHub 链接中包含本书的正文。
这是有问题的代码:
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”,但在 Node 中打印“name: undefined”。
有人可以解释一下这种差异的方式和原因吗?是否可以对 softBind 函数进行更改,从而使代码在两种环境中都能以相同的方式工作?
最佳答案
从记录 bound
内 this
的值可以看出,当函数作为 setTimeout
回调调用时,this
被设置为一个特殊的超时对象:
{ _idleTimeout: 10,
_idlePrev: null,
_idleNext: null,
_idleStart: 1417462313179,
_monotonicStartTime: 36214497,
_onTimeout: [Function: bound],
_repeat: false }
即它不引用全局对象,与浏览器中的setTimeout
不同。这就是为什么
(typeof global !== "undefined" && this === global)
未满足,foo
的 this
设置为超时对象,而不是 obj
。
关于javascript - 与浏览器中的全局范围相比,node.js 中的全局范围有何不同(带有具体示例)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27235616/