backbonejs 函数未定义
backbonejs function is is not defined
我遇到一个未定义的函数。
我正在获取键值对并在 forEach 上执行函数。
结构
var AppView = Backbone.View.extend({
initialize: function() {
this.render();
},
render: function() {
this.$el.html("Hello World");
this.one();
},
one: function() {
this.two();
},
two: function() {
var object = {
"labname4": "423",
"Path": "4",
"X": "4"
};
console.log('two');
Object.keys(object).map(function(objectKey, index) {
var value = object[objectKey];
this.three();
});
},
three: function() {
console.log('three');
},
});
var appView = new AppView();
console.log("done");
使用:
- jquery/1.7.2
- 下划线.js/1.3.3
- backbone.js/0.9.2
这是使用嵌套函数时的常见错误,例如:
Object.keys(object).map(function(objectKey, index) {
var value = object[objectKey];
this.three();
});
此处 this.three()
、this
不再引用您的对象,因为它在嵌套函数范围内并且未在其上定义方法 three()
。
有 2 种可能的解决方案:
a) 使用 clojure
而不是嵌套函数。您可以编写相同的代码,例如:
Object.keys(object).map((objectKey, index) => { // note the arrow and no 'function' keyword
var value = object[objectKey];
this.three();
});
clojure
保留在当前范围内,因此 this.three()
将起作用,另一方面,function
定义了它自己的范围。
b) 如果您希望它在特定范围内执行,您可以绑定 function
,例如:
Object.keys(object).map(function(objectKey, index) {
var value = object[objectKey];
this.three();
}.bind(this)); // note '.bind(this)'
这样 function
将使用您当前的范围,而不是创建一个新范围。
这两种方法都是有效的,由用户选择一种,我个人更喜欢 clojures
.
因为您在调用 Object.keys(object).map 时更改了范围,所以这也会更改,因此您无法通过使用它来访问原始值。将它别名为 that 允许您仍然访问 this 的原始值。您的代码将如下所示。
var AppView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
this.$el.html("Hello World");
this.one();
},
one: function(){
this.two();
},
two: function(){
var that = this;
var object = { "labname4": "423",
"Path": "4",
"X": "4"};
console.log('two');
Object.keys(object).map(function(objectKey, index) {
var value = object[objectKey];
that.three();
});
},
three: function(){
console.log('three');
},
});
var appView = new AppView();
console.log("done");
编辑 1 var that = this vs bind
对我来说,似乎 .bind 确实有一席之地。例如,当你在一个变量中有一个函数并且你想将它附加到一个特定的 this 上时。
也就是说,对于嵌套的匿名函数,我认为使用 var that = this;与使用 .bind 相比,简单明了,需要更少的心理账户。例如,假设我们有两个嵌套函数:
function foo() {
return (function() {
doSomething((function() {
return this.name; // what is `this` again?
}).bind(this));
}).bind(this);
}
对比
function foo() {
var that = this;
return (function() {
doSomething((function() {
return that.name; // `that` is easy to know because its defined
})
})
}
当然,因为这是风格问题,"mental accounting"的问题因人而异。但对我来说,考虑到 Javascript 的语义,我认为当你有嵌套回调时,that = this 很容易理解。
我遇到一个未定义的函数。
我正在获取键值对并在 forEach 上执行函数。
结构
var AppView = Backbone.View.extend({
initialize: function() {
this.render();
},
render: function() {
this.$el.html("Hello World");
this.one();
},
one: function() {
this.two();
},
two: function() {
var object = {
"labname4": "423",
"Path": "4",
"X": "4"
};
console.log('two');
Object.keys(object).map(function(objectKey, index) {
var value = object[objectKey];
this.three();
});
},
three: function() {
console.log('three');
},
});
var appView = new AppView();
console.log("done");
使用:
- jquery/1.7.2
- 下划线.js/1.3.3
- backbone.js/0.9.2
这是使用嵌套函数时的常见错误,例如:
Object.keys(object).map(function(objectKey, index) {
var value = object[objectKey];
this.three();
});
此处 this.three()
、this
不再引用您的对象,因为它在嵌套函数范围内并且未在其上定义方法 three()
。
有 2 种可能的解决方案:
a) 使用 clojure
而不是嵌套函数。您可以编写相同的代码,例如:
Object.keys(object).map((objectKey, index) => { // note the arrow and no 'function' keyword
var value = object[objectKey];
this.three();
});
clojure
保留在当前范围内,因此 this.three()
将起作用,另一方面,function
定义了它自己的范围。
b) 如果您希望它在特定范围内执行,您可以绑定 function
,例如:
Object.keys(object).map(function(objectKey, index) {
var value = object[objectKey];
this.three();
}.bind(this)); // note '.bind(this)'
这样 function
将使用您当前的范围,而不是创建一个新范围。
这两种方法都是有效的,由用户选择一种,我个人更喜欢 clojures
.
因为您在调用 Object.keys(object).map 时更改了范围,所以这也会更改,因此您无法通过使用它来访问原始值。将它别名为 that 允许您仍然访问 this 的原始值。您的代码将如下所示。
var AppView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
this.$el.html("Hello World");
this.one();
},
one: function(){
this.two();
},
two: function(){
var that = this;
var object = { "labname4": "423",
"Path": "4",
"X": "4"};
console.log('two');
Object.keys(object).map(function(objectKey, index) {
var value = object[objectKey];
that.three();
});
},
three: function(){
console.log('three');
},
});
var appView = new AppView();
console.log("done");
编辑 1 var that = this vs bind
对我来说,似乎 .bind 确实有一席之地。例如,当你在一个变量中有一个函数并且你想将它附加到一个特定的 this 上时。
也就是说,对于嵌套的匿名函数,我认为使用 var that = this;与使用 .bind 相比,简单明了,需要更少的心理账户。例如,假设我们有两个嵌套函数:
function foo() {
return (function() {
doSomething((function() {
return this.name; // what is `this` again?
}).bind(this));
}).bind(this);
}
对比
function foo() {
var that = this;
return (function() {
doSomething((function() {
return that.name; // `that` is easy to know because its defined
})
})
}
当然,因为这是风格问题,"mental accounting"的问题因人而异。但对我来说,考虑到 Javascript 的语义,我认为当你有嵌套回调时,that = this 很容易理解。