在匿名函数中访问它

时间:2013-08-24 21:45:44

标签: javascript

我想创建一个具有自己范围的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();

我知道它失败了,因为它没有引用Ff对象。

有没有办法访问它?

2 个答案:

答案 0 :(得分:6)

立即调用的函数表达式(IIFE)本身只被调用一次,对increment的所有调用都将使用上次离开时​​的变量,而不是重新var它们。

使用callapplybind

更改调用上下文
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将被正确设置。