Stoyan Stefanov:JavaScript模式-回调和作用域
在“回调和作用域”一节的第4章(函数)中,您可以找到以下示例:Stoyan Stefanov:JavaScript模式-回调和作用域,javascript,design-patterns,callback,this,Javascript,Design Patterns,Callback,This,在“回调和作用域”一节的第4章(函数)中,您可以找到以下示例: var myapp = {}; myapp.color = "green"; myapp.paint = function (node) { node.style.color = this.color; }; var findNodes = function (callback) { // ... if (typeof callback === "function") { callback(
var myapp = {};
myapp.color = "green";
myapp.paint = function (node) {
node.style.color = this.color;
};
var findNodes = function (callback) {
// ...
if (typeof callback === "function") {
callback(found);
}
// ...
};
在我的这本(电子)书中,作者写道:
“如果调用findNodes(myapp.paint),它将无法按预期工作,因为不会定义this.color。此对象将引用全局对象,因为findNodes()是作为函数而不是方法调用的。如果findNodes()是作为名为dom的对象(如dom.findNodes()的对象)的方法定义的,则回调的内部将引用dom,而不是预期的myapp。“
我不明白这个解释。也许作者错了
在我看来,这个论点是误导性的。如果FinIndicates()作为方法调用或作为函数调用,则与方法myapp.paint()中的此值无关。在任何一种情况下,该值都将引用全局对象,因为它是由调用“callback(found)”的形式确定的(请参阅)
谁能帮我找到正确的答案 作者错了。他可能在解释中误用了
findNodes
作为paint
- 调用myapp.paint()将此绑定到myapp对象
- 调用var func=myapp.paint;func()将此绑定到全局窗口对象
你的想法是正确的
this
insidefindNodes
将是全局对象或另一个对象,但this
insidecallback
将始终是全局对象
补救办法之一是:
var findNodes = function (callback) {
// ...
if (typeof callback === "function") {
callback.call(this,found); // CHANGED HERE
}
// ...
};
这样,findNodes的作用域将传递给回调。这至少会使作者正确
更常见的处理回调的方法是提供一个可选参数来定义范围:
var findNodes = function (callback, scope) {
// ...
if (typeof callback === "function") {
callback.call(scope,found); // CHANGED HERE
}
// ...
};
谢谢你的回答!我还试图“修复”作者的论点。除了最后一句话外,你正确的解释对我来说更有意义。为什么paint()应该是dom的一种方法?是的,这对我来说也没有意义@蒂博斯的答案更准确。