在“回调和范围”部分的第4章(功能)中,您可以找到以下示例:
var myapp = {};
myapp.color = "green";
myapp.paint = function (node) {
node.style.color = this.color;
};
var findNodes = function (callback) {
// ...
if (typeof callback === "function") {
callback(found);
}
// ...
};
在我的这本(e-)书的版本中,作者写道:
“如果你调用findNodes(myapp.paint),它将无法按预期工作,因为不会定义this.color。这将引用全局对象的对象,因为findNodes()被调用为函数,如果将findNodes()定义为一个名为dom的对象的方法(如dom.findNodes()),则回调内部将引用dom而不是预期的myapp。“
我不明白这个解释。也许作者错了?
在我看来,这种说法具有误导性。如果findeNotes()作为方法调用或作为函数调用,则与myapp.paint()方法中的this-value无关。在任何一种情况下,this-value都将引用全局对象,因为它由调用“callback(found)”的形式决定(参见http://dmitrysoshnikov.com/ecmascript/javascript-the-core/#this-value)。
任何人都可以帮我找到正确的答案吗?
答案 0 :(得分:0)
作者错了。他可能在findNodes
中误解paint
作为解释。
更正的说明可能如下所示
如果你调用findNodes(myapp.paint),它将无法按预期工作, 因为this.color不会被定义。这将引用的对象 全局对象,因为 paint ()作为函数调用,而不是作为函数调用 方法。如果 paint ()被定义为名为dom的对象的方法 (比如dom。 paint ()),然后这个回调内部会引用 dom而不是预期的myapp。
答案 1 :(得分:0)
你的想法是正确的。 this
内的findNodes
可以是全局对象,也可以是其他对象,但this
内的callback
将始终是全局对象。
解决问题的一种方法是:
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
}
// ...
};