在创建原型函数期间的回调集中将“this”设置为实例

时间:2015-08-18 17:33:25

标签: javascript prototype javascript-objects

我有这段代码:

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),但它缺少构造函数中设置的所有宝贵实例字段。

我知道我可以在构造函数中简单地设置this.allEventsSelectedClickedHandler,但我正在尝试将方法创建与变量分开。

4 个答案:

答案 0 :(得分:1)

问题是调用selectablesArrayGetter();,它确定了回调的this value

您需要使用call“传递”调用方法(即您要返回的闭包)的this值:

var array = selectablesArrayGetter.call(this);

答案 1 :(得分:0)

我建议您按照以下方式定义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;
    });
};

答案 2 :(得分:0)

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

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

工作小提琴:http://jsfiddle.net/michaschwab/coegnL5j/9/也有Bergi的答案(已注释掉),以表明它的效果也一样。

答案 3 :(得分:0)

好的,这就是我做的。

在原型定义中,我不是直接将它与<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/mm_drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Source: http://developer.android.com/training/implementing-navigation/nav-drawer.html --> <!-- The main content view --> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Source: http://android-developers.blogspot.in/2014/10/appcompat-v21-material-design-for-pre.html --> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mm_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/actionBarSize" android:layout_alignParentTop="true" style="@style/MMActionBar" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> <!-- The FrameLayout where I replace Fragments --> <FrameLayout android:id="@+id/mm_content_frame" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/mm_toolbar"/> </RelativeLayout> <ListView android:id="@+id/mm_drawer_listview" android:layout_width="260dp" android:layout_height="match_parent" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingStart="16dp" android:layout_gravity="start" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="0dp" android:background="@color/mm_white" /> </android.support.v4.widget.DrawerLayout> 函数关联,而是实际定义了一个返回createAllAreSelectedClickedHandler函数的函数。通过这样做,我可以定义一个变量(在本例中为protoScope),该变量在定义时映射此上下文。 这样做时,如果在createAllAreSelectedClickedHandler函数中放置断点,您将看到createAllAreSelectedClickedHandler值正确(acutal registrations数组)。

selectablesArrayGetter