2

私は JavaScript の初心者ではありませんが、その柔軟な方法 (匿名関数をコールバックとそのスコープとして定義するなど) が非常に混乱することがよくあります。私がまだ苦労していることの1つは、クロージャーとスコープです。

次の例を見てください (バックボーン モデルから):

'handleRemove': function() {
    var thisModel = this;
    this.view.$el.slideUp(400, function() { thisModel.view.remove(); });
},

モデルが削除/削除された後、ビューがアニメーション化され、最終的に DOM から削除されます。これは問題なく動作しますが、最初は次のコードを試しました。

'handleRemove': function() {
    var thisModel = this;
    this.view.$el.slideUp(400, thisModel.view.remove );
},

これは基本的に同じですがfunction() {}、remove() 呼び出しのラッパーがありません。

後者のコードが機能しない理由を誰かが説明できますか? 次の例外/バックトレースが発生します。

Uncaught TypeError: Cannot call method 'remove' of undefined backbone-min.js:1272
_.extend.remove backbone-min.js:1272
jQuery.speed.opt.complete jquery-1.8.3.js:9154
jQuery.Callbacks.fire jquery-1.8.3.js:974
jQuery.Callbacks.self.fireWith jquery-1.8.3.js:1084
tick jquery-1.8.3.js:8653
jQuery.fx.tick

ありがとうございました!

4

1 に答える 1

3

これthisは、コールバック関数のコンテキスト()がjQueryによってアニメーション化されている要素に変わるためです。

var obj = { fn: function() {         // Used as below, the following will print:
                alert(this === obj); // false
                alert(this.tagName); // "DIV"
          }};
$('<div>').slideUp(400, obj.fn);

さらに、Backboneのview.remove関数は次のようになります(ソースコード)。

remove: function() {
  this.$el.remove();
  this.stopListening();
  return this;
},

thisはバックボーンビューオブジェクトではなくなったため、$elは定義されていません。したがって、「未定義のメソッド'remove'を呼び出せません」というエラーが発生します。

エラーを回避する別の方法は、アンダースコアの_.bind方法を使用することです。

this.view.$el.slideUp(400, _.bind(thisModel.view.remove, this) );
于 2013-02-09T10:12:19.157 に答える