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另存为thatthis也很常见。

下划线使用.call()更改传递给它的迭代器函数的this。具体来说,_.each()具有第三个参数,它允许您指定想要this是什么,因此该示例是正确的。请参见underscore.js source

10-07 19:17
查看更多