Javascript “的范围”;这";在子对象内定义函数时
我正在扩展一个主干视图,其中包含关于在另一个类中计算的页脚的自定义选项 它看起来像:Javascript “的范围”;这";在子对象内定义函数时,javascript,backbone.js,scope,this,Javascript,Backbone.js,Scope,This,我正在扩展一个主干视图,其中包含关于在另一个类中计算的页脚的自定义选项 它看起来像: var EditUserView = Backbone.View.extend({ footer: { name: "Hello", label: function() { //Return "Create" if it's a new model without id, or else "Save" return this
var EditUserView = Backbone.View.extend({
footer: {
name: "Hello",
label: function() {
//Return "Create" if it's a new model without id, or else "Save"
return this.model.id ? "Save" : "Create";
}
}
});
如您所见,属性应该可以定义为返回字符串的函数或正常字符串值。
在FooterView中,我使用3;结果评估这些选项:
initialize: function(options) {
//"options" is the footer-object from the view.
this.data = {
name: _.result(options, "name"),
label: _.result(options, "label")
};
}
但问题是,在我上面定义的label函数中,我无法访问这个EditUserView。我也不能定义一个var=this
,因为我扩展的对象没有地方放局部变量。
如何使我在footer对象中定义的函数具有UserEditView的此范围
我也同意:
footer: {
name: "Hello",
label: this.getName
},
getName: function() {
return this.model.id? "Save":"Create";
}
如果另一种方法不可能,或者这种方法更容易实现。一般来说,函数内部的
这只取决于函数的调用方式(当然,除非您有绑定函数)。鉴于此:
var V = Backbone.View.extend({
m: function() { console.log(this) }
});
var v = new V;
然后它们做不同的事情:
var f = v.m; f();
v.m();
它们调用的是相同的函数,但在第一种情况下,这个
将是全局对象,在第二种情况下,它将是v
;区别不在于函数本身,而在于它的调用方式
如果我们看一下,我们可以看到它是如何调用函数的:
_.result = function(object, property) {
if (object == null) return void 0;
var value = object[property];
return _.isFunction(value) ? value.call(object) : value;
};
注意其中的,这意味着如果m
是obj
的函数属性,则表示.result(obj,'m')
与表示:
obj.m()
将其应用于您的:
_.result(options, "label")
我们看到你实际上是在说:
options.label()
而此
在标签内
功能将是选项
我在上面提到了绑定函数。创建绑定函数的官方方法是使用:
bind()方法创建一个新函数,在调用该函数时,将其this
关键字设置为提供的值,在调用新函数时,在任何提供的参数之前都有一个给定的参数序列
这意味着您可以使用bind
指定函数中的内容,而不管函数如何调用。您还可以使用、和各种其他方法来模拟函数上的本机bind
方法
在视图的initialize
中,可以将footer
中的函数绑定到相应的this
。但是请注意,您必须克隆整个页脚
,以避免意外地通过原型共享内容:
initialize: function() {
var footer = {
name: this.footer.name,
label: this.footer.label.bind(this)
};
this.footer = footer;
}
这显然是通过使用任何组合来概括的,迭代器使您感到高兴
这样做的缺点是视图的每个实例都有自己的footer
副本,如果实例太多或footer
太大,这可能会造成浪费。如果这是一个问题,那么您可以编写自己版本的。.result
,类似以下内容(未测试的代码):
然后说:
_.i_cant_think_of_a_good_name_for(this, options.name);
_.i_cant_think_of_a_good_name_for(this, options.label);
在你看来。请注意,这里的第一个参数是您希望用于函数的this
,第二个参数是整个属性,而不仅仅是它的名称。您可以使用.bind(this)吗?如果您在我的示例中告诉我在哪里调用它,我认为没有理由不这样做。
_.i_cant_think_of_a_good_name_for(this, options.name);
_.i_cant_think_of_a_good_name_for(this, options.label);