设置“this"到实例,在创建原型函数期间的回调集中

Setting "this" to the instance, in a callback set during the creation of a prototype function

本文关键字:函数 原型 创建 集中 回调 this quot 实例 设置      更新时间:2023-09-26

我有这样的代码:

var createAllAreSelectedClickedHandler = function(selectablesArrayGetter) {
    return function() {
        var array = selectablesArrayGetter();
        var desiredState = array.every(function(selectable) { return selectable.selected; }) ? false : true;
        array.forEach(function(selectable) {
            selectable.selected = desiredState;
        });
    };
};

后面接这个

function PromoViewModel() { this.registrations = [...] }   
PromoViewModel.prototype.allEventsSelectedClickedHandler = createAllAreSelectedClickedHandler(function() { return this.registrations; }));

我无法设置正确的值。当函数被创建时,"this"值指向Window,所以我不能执行.bind(this)。我试过做。bind(PromoViewModel.prototype),但它缺乏构造函数内设置的所有宝贵的实例字段。

我知道我可以简单地设置这个。allEventsSelectedClickedHandler中的构造函数,但我试图将方法创建与变量分开。

问题在于调用selectablesArrayGetter();,它决定了回调的this值。

您将需要"传递"this值,该方法(即您正在返回的闭包)被调用,使用call:

var array = selectablesArrayGetter.call(this);

我建议这样定义你的PromoViewModel.prototype.allEventsSelectedClickedHandler方法:

PromoViewModel.prototype.allEventsSelectedClickedHandler = function() {
    var _array = this.registrations;
    var desiredState = _array.every(function(selectable) { return selectable.selected; }) ? false : true;
    _array.forEach(function(selectable) {
        selectable.selected = desiredState;
    });
};

您作为回调传递的函数使用this,但没有PromoViewModel上下文。您可以通过将this绑定到一个变量来确保该方法具有适当的上下文。

function PromoViewModel()
{
    var me = this;
    this.registrations = [...];
    this.allEventsSelectedClickedHandler = createAllAreSelectedClickedHandler(function() {
        return me.registrations;
    });
}  

Working fiddle: http://jsfiddle.net/michaschwab/coegnL5j/9/也有Bergi的答案在那里(注释掉),以表明它工作得一样好。

我是这么做的

在原型定义中,我没有将其直接关联到createAllAreSelectedClickedHandler函数,而是定义了一个返回createAllAreSelectedClickedHandler函数的函数。通过这样做,我可以定义一个变量(在这个例子中是protoScope),它在定义时映射这个上下文。这样做时,如果在createAllAreSelectedClickedHandler函数中设置一个断点,您将看到selectablesArrayGetter值是正确的(实际的注册数组)。

PromoViewModel.prototype.allEventsSelectedClickedHandler = function (){
    var protoScope = this;
    return createAllAreSelectedClickedHandler(function() { 
        return protoScope.registrations; 
    });
}