var PlaylistView = Backbone.View.extend({
el: '#expanded-container',
initialize: function() {
this.bg = chrome.extension.getBackgroundPage();
this.$('.list-group').empty();
var realThis = this;
_.each(this.bg.Playlist.models, function (song) {
// append to playlist, rendering song template?
var songView = new SongView({ model: song });
console.log(realThis); // THIS is what I want
console.log(this) // this is NOT what I want
//this.$el.append(songView.render().el); // hence, this does NOT work
realThis.$el.append(songView.render().el); // and THIS works
});
}
});
在上面的代码中,
this
函数内的_.each()
指向全局window
对象,因为窗口会调用_.each()
。但是,我仍然希望this
指向PlaylistView
。我曾经遇到过许多类似的情况,并且我经常定义一个变量来存储此变量的初始值,就像提供的示例中的realThis
变量一样。还有其他常规方法可以解决此问题吗?注意:我正在按照this书来学习Backbone,并且它以下面的代码为例。
var ListView = Backbone.View.extend({
render: function(){
// Assume our model exposes the items we will
// display in our list
var items = this.model.get('items');
// Loop through each of our items using the Underscore
// _.each iterator
_.each(items, function(item){
// Create a new instance of the ItemView, passing
// it a specific model item
var itemView = new ItemView({ model: item });
// The itemView's DOM element is appended after it
// has been rendered. Here, the 'return this' is helpful
// as the itemView renders its model. Later, we ask for
// its output ("el")
this.$el.append( itemView.render().el ); // <--- *THIS IS WRONG?
}, this);
}
});
在这种情况下,
this
循环内的_.each
不会像我的代码中那样指向错误的对象吗?这是书中的错误吗?还是我误会了什么?谢谢!参考:Learning this keyword
最佳答案
您可以使用this
更改特定功能的.bind()
:
function foo() {
alert(this.x);
}
var boundFoo = foo.bind({x: "bar"});
boundFoo();
这会提醒“栏”。
如果要同时访问内部和外部
this
,将外部realThis
另存为that
或this
也很常见。下划线使用
.call()
更改传递给它的迭代器函数的this
。具体来说,_.each()
具有第三个参数,它允许您指定想要this
是什么,因此该示例是正确的。请参见underscore.js source。