这段代码是javascript中构造函数体的一部分:
window.addEventListener("load", function(){
this._updateFilter();
}.bind(this));
_updateFilter方法属于构造函数的原型对象:
Constructor.prototype._updateFilter = function(){
// some code
};
我对_updateFilter在构造函数的新实例创建之前调用的东西感到困惑。所以没有:
var obj = new Constructor();
但是_updateFilter被onload调用?有人能解释一下吗?
谢谢
仅仅因为定义了侦听器回调甚至构造函数本身并不意味着它在定义时被调用。实际上,构造函数只是一个函数。与任何函数声明一样,它定义了调用时将发生的事情。如果我们不调用它,什么也不会发生。对于构造函数,在创建它的新实例时调用它。最终,你的应用程序将调用构造函数,下面是将发生的事情:
-
使用特殊的
new
关键字,我们告诉JavaScript解释器调用构造函数并在其中提供一个新对象。 -
解释器将构造函数中的
this
设置为内存中对该新对象的引用。 -
下一步,在
window
上创建一个事件监听器。我们将一个回调函数传递给该侦听器,该侦听器是this
对象的闭包,使当前的this
引用可用。但是这个回调还没有执行,直到窗口的load
事件触发。 -
假设它立即触发(即实际上不是回调),我们就会有问题。尽管当时
this
已经存在,并且实际上已经继承了Constructor.prototype
,但它没有_updateFilter
这样的方法。然后解释器将检查原型链,并看到Constructor.prototype
上也没有这样的函数。它将继续沿着链向上查找,找不到函数,并抛出一个错误。但是记住,回调还没有触发。 -
回到实际发生的事情:接下来我们用新方法
_updateFilter
扩展Constructor
的原型。 -
所以最终窗口的
load
事件被触发,回调被调用。解释器检查_updateFilter
是否存在于this
上,如果不存在,则检查其原型链。现在它发现Constructor.prototype
上确实存在该函数,并运行该代码。