下面的两个代码块在上下文中工作,并且看起来完全在功能上等效。我理解js prototypes相当合适,所以我本身并不是在询问它们(除非是唯一的区别)。
相反,比较两种简单的方法将方法放在视图模型上,如下所示, Knockout 有任何影响/差异,例如:约束时间?
define([“knockout”,“text!。/ home.html”],function(ko,homeTemplate){//< - An AMD Module
function HomeViewModel(route) { var self = this; self.message = ko.observable('Snacks!'); self.eatSomething = function () { self.message('Yum, a viewmodel snack.'); }; } return { viewModel: HomeViewModel, template: homeTemplate }; });
与通过原型添加方法:
define([“knockout”,“text!。/ home.html”],function(ko,homeTemplate){
function HomeViewModel(route) { this.message = ko.observable('Snacks!'); }; HomeViewModel.prototype.eatSomething = function () { this.message('Yum, the same viewmodel snack, only different?'); }; return { viewModel: HomeViewModel, template: homeTemplate };
});
(代码是通过Yeoman's输出的Knockout generator脚手架的简单模型。它创建了knockout component的锅炉板代码,这是一个相当近期的(KO 3.2),非常受欢迎一个不错的KO组件解释器是here.)
答案 0 :(得分:13)
在第一个示例中,由于函数使用self
(设置为对新实例的引用)而不是this
,因此无论函数如何被调用/绑定,它总是会正确设置自己的message
observable。
在第二个例子中,当正常绑定到像data-bind="click: eatSomething"
这样的函数时,你会得到相同的结果。 Knockout调用函数,其值this
等于当前数据。
如果你有一个需要从不同的上下文调用该函数的场景(可能你的视图模型有一个你正在使用的with
或模板的子对象)。然后你可以使用像data-bind="click: $parent.eatSomething"
这样的绑定。 KO仍会调用this
等于当前数据(不是$parent
)的函数,因此您会遇到问题。
将函数放在原型上的一个好处是,如果你创建了许多HomeViewModel
个实例,它们将通过原型共享相同的eatSomething
函数,而不是每个实例都有自己的eatSomething
函数的副本。这可能不是您方案中的问题,因为您可能只有一个HomeViewModel
。
您可以通过调用上下文来确保上下文正确:data-bind="click: $parent.eatSomething.bind($parent)
。使用此调用,将创建一个新的包装函数,该函数使用适当的上下文(值this
)调用原始函数。或者,您也可以在视图模型中绑定它以保持绑定更清晰。无论哪种方式,你确实失去了将它放在原型上的一些价值,因为你正在为每个实例创建包装函数。 "胆量"该函数至少只会在原型上存在一次。
我倾向于在我的代码中使用原型,但毫无疑问,使用self
技术(或类似揭示模块模式)可以减少您对this
的值的关注。 / p>