何时在knockoutjs原型中使用.bind(this)

时间:2014-05-21 23:17:32

标签: javascript knockout.js

我正在学习knockout.js并在jsfiddle上找到了很多有趣且有用的样本。我正在查看一些knockout.js示例,它使用object.prototype将方法添加到viewmodel对象。在某些示例中,它还在viewmodel中定义了一个方法并使用.bind(this),而在其他示例中,它不会执行此操作。所以我不明白你何时必须使用.bind(this)和使用原型添加的方法?

例如,this sample使用原型向ViewModel对象添加了一些方法,但它也在viewmodel中定义了这些方法,然后使用.bind(this)。我不明白为什么它需要这样做,因为我发现another sample它没有在viewmodel中声明相同的方法并使用.bind(this)。

var ViewModel = function(items) {
    this.selectItem = this.selectItem.bind(this);
    this.acceptItem = this.acceptItem.bind(this);
    this.revertItem = this.revertItem.bind(this);
}
ko.utils.extend(ViewModel.prototype, {
    //select an item and make a copy of it for editing
    selectItem: function(item) {
        this.selectedItem(item);
        this.itemForEditing(new Item(ko.toJS(item)));
    },

    acceptItem: function(item) {
        if (item.errors().length == 0) { //Check if ViewModel has any errors
            alert('Thank you.');
        var selected = this.selectedItem(),
            edited = ko.toJS(this.itemForEditing()); //clean copy of edited

        //apply updates from the edited item to the selected item
        selected.name.update.call(selected, edited);

        //clear selected item
        this.selectedItem(null);
        this.itemForEditing(null);
        }

        else {
            alert('Please check your submission.');
            item.errors.showAllMessages();
        }
    },

    //just throw away the edited item and clear the selected observables
    revertItem: function() {
        this.selectedItem(null);
        this.itemForEditing(null);
    }
});

1 个答案:

答案 0 :(得分:1)

JavaScript并没有像其他语言那样的方法概念。考虑这个对象:

function Foo() {
    this.foo = 12;
    this.bar = function() {
        console.log('This is', this, 'and this.foo is', this.foo);
    };
}

使用var f = new Foo()创建新实例时,可以调用其bar属性,该属性恰好是一个函数:

> var f = new Foo()
> f.bar()
This is { foo: 12, bar: [Function] } and this.foo is 12

但是f.bar并非真正一种方法,例如Python方法,它既可以绑定也可以不绑定。恰好是对象属性的JavaScript函数始终是未绑定的:

> var b = f.bar
> b()
This is Window {...} and this.foo is undefined

如果未作为f的属性调用,this将成为根对象。实际上,调用f.bar()隐式将this的{​​{1}}对象设置为f.bar,如下所示:

f

要使> b.call(f) This is { foo: 12, bar: [Function] } and this.foo is 12 更像绑定方法,可以使用f.barf.bar绑定到特定this,因此上一个示例可以按照您的预期运行:

.bind