Javascript “为什么”的上下文;这";这个例子有什么变化?

Javascript “为什么”的上下文;这";这个例子有什么变化?,javascript,jquery,scope,Javascript,Jquery,Scope,我不好意思承认我花了多少时间试图解决这个问题。事实证明,“problem area”注释下两行的顺序在原型addSong函数中使用时会改变“this”的上下文 var PlaylistView = function(config){ this.config = config || {}; this.$addSongForm = this.config.addSongForm || $('#addSongForm'); this.$song = this.config.s

我不好意思承认我花了多少时间试图解决这个问题。事实证明,“problem area”注释下两行的顺序在原型addSong函数中使用时会改变“this”的上下文

var PlaylistView = function(config){

    this.config = config || {};
    this.$addSongForm = this.config.addSongForm || $('#addSongForm');
    this.$song = this.config.song || $('#song');

    // problem area
    this.addSong = $.proxy(this.addSong, this);
    this.listenAddSong();
  };

PlaylistView.prototype.listenAddSong = function(){
    this.$addSongForm.on('submit', this.addSong);
};

PlaylistView.prototype.addSong = function(event){
    //Here is where I'm getting different context for this
    var songName = this.$song.val();
    //do some stuff...
    return false;
};

return PlaylistView;
当这两行按显示的顺序排列时,我得到了我想要的行为:“this.$song”包含一个jquery选择器,我在初始化PlayView对象时设置了该选择器。然而,当我颠倒顺序时,在Firefox中查看inspector时发现“this”指的是DOM中的实际表单。
为什么会这样?

原因是
this.addSong!==$。代理(this.addSong,this)
。当您运行
$.proxy
然后
listenadsong
时,将使用绑定函数,
是您的
播放列表
对象。当您颠倒顺序时,unbound函数将在
listenadsong
中传递给侦听器。用此行中的绑定函数替换未绑定函数:

this.addSong = $.proxy(this.addSong, this);

因此,当运行
listenadSong
时,根据this.addSong指向哪个函数,您要么得到正确的行为,要么得到不正确的行为。

没有人能够确定this在您的代码中指的是什么,由于
的值可以通过
进行更改,因此
的值可以通过
进行更改。应用
绑定
调用
等。。