我正在学习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);
}
});
答案 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.bar
将f.bar
绑定到特定this
,因此上一个示例可以按照您的预期运行:
.bind