Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript “的范围”;这";在子对象内定义函数时_Javascript_Backbone.js_Scope_This - Fatal编程技术网

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);