JavaScript'这个'关键词

时间:2014-04-17 01:32:26

标签: javascript underscore.js this

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

2 个答案:

答案 0 :(得分:2)

来自http://underscorejs.org/#each

  

每个_.each(list, iterator, [context])

     

迭代器绑定到上下文对象(如果有)。

initialize()内,this指向您的主干视图。如果将this作为第3个参数传递给_.each(),那么this将在迭代器函数中引用您的Backbone视图。

  

我遇到过很多类似的情况,我经常定义一个变量   存储了这个的初始值,就像realThis变量一样   提供的例子。还有其他传统的处理方式吗?   此?

是。如果您在ES5(非IE8)环境中,请使用Function.prototype.bind()。为了向后兼容,请使用_.bind()

var func = function (greeting) {
  return greeting + ': ' + this.name;
};

if (usingUnderscore) {
  func = _.bind(func, {name: 'moe'}, 'hi');
} else if (es5environmentHooray) {
  func = func.bind({name: 'moe'}, 'hi');
}

func();
=> 'hi: moe'

答案 1 :(得分:1)

您可以使用this

更改特定功能的.bind()
function foo() {
    alert(this.x);
}
var boundFoo = foo.bind({x: "bar"});
boundFoo();

此提醒&#34; bar&#34;。

如果您想要访问内部和外部this,则将realThis保留为thatthis也很常见。

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