我想创建一个具有自己范围的prototype
函数。为此,我使用匿名函数,但我找不到访问对象成员的方法。
这是我想要实现的简化版本:
function F() {
this.counter = 0;
}
F.prototype.increment = (function() {
var lastIncrementTime = -1;
var caller = this; // <--- it fails here because this is the Window object
return function(time) {
if (time > lastIncrementTime) {
caller.counter++;
lastIncrementTime = time;
return caller.counter;
}
return caller.counter;
}
})();
f = new F();
f.increment();
我知道它失败了,因为它没有引用F
或f
对象。
有没有办法访问它?
答案 0 :(得分:6)
立即调用的函数表达式(IIFE)本身只被调用一次,对increment
的所有调用都将使用上次离开时的变量,而不是重新var
它们。
F.prototype.increment = (function() {
// this === F.prototype
// ...
}).call(F.prototype);
此示例上下文中的this
不是特定于实例的,而是原型。
看起来你实际上想要实现一些不同的东西,你有一个独立的函数来在构造实例时用它自己的闭包来初始化一个特定于实例的属性。这些类型的操作可能占用一些内存,因此不要存储太多的唯一数据。
function F() {
this.counter = 0;
this.__init_increment(); // create `this.increment`
}
F.prototype.__init_increment = function () {
var lastIncrementTime = -1;
this.increment = function (time) {
if (time > lastIncrementTime) {
this.counter++;
lastIncrementTime = time;
}
return this.counter;
};
};
var f = new F();
f.increment(0); // 1
f.increment(0); // 1
f.increment(5); // 2
在此示例中,this.increment
是每个实例的不同函数,这意味着每个实例都有不同的闭包。它们由原型中的函数生成,它设置实例属性。生成器不必在原型中,只需记住将其应用于实例时的调用上下文。
答案 1 :(得分:2)
将您的var caller = this
移到匿名函数中,其中this
将被正确设置。