Underscoreの_を慎む.bindAll(this)
3069 ワード
bindAllについて
アンロード・スコープ 私が大好きなJSライブラリです.先端の開発を簡単にするために、かなり便利なツールを提供しています.一番印象に残っています.好きな方法はbindAllです.たとえば:
その後、BackboneのViewを使う時、この方法は更に私の標準装備になりました.model事件のモニターコールバック関数はデフォルトではthisはmodel自身を指すので、3番目のパラメータを追加で伝達しないと変えられません.これは私など怠け者にはとても受け入れられないです.
このようないい日が長く続いています.私が使い始めるまで. マルオネット 穴に落ちて、やっと見つけました.
原因分析
本来私たちはUsersクラスで定義された方法を自動bindで一回だけ見たいですが、重要な点を見逃しました.
model属性に対応するUserは実はfunctionなので、bindにも使われています. !
ああ、愚かですね.Javascriptには類がないです.functionだけです.
しかし、なぜIEの下でエラーが発生しました.Chromeの下で大丈夫ですか?なぜならbindの機能はECMAScript 5のFunction.prototype.bindと同じです.ChromeはECMAScript 5をサポートしていますので、この時はブラウザの元の方法を優先的に採用します.IE 8などの旧式のブラウザに対して、それは相応のfallbackを提供して実現します.MDNで調べてみました bindメソッドのドキュメント ,中には、bindによって過ぎたfunctionにnew操作符を使えば、thisは変わらないと述べています.残念なことに、Underscore 1.4.4里のfallbackは非常に簡単に実現され、newオペレータの問題を考慮していないので、悲劇になりました.
解決方法
はい、もうここに来ました.どうすればいいですか?Underscoreの新しいバージョンを確認しましたが、1.5.1の中のbindはもうこの問題を修復しました.newオペレータとよく協力できました.しかし、1.5.1はビッドオールの方法を重大に調整しました.
Removed the ability to call_.bindAll withのmethod name argments.It's pretty much always wiser to white-list the names of the methods you'd like to bind.
つまり、新バージョンはもうサポートされていません.
何時に補充しますか
PS 1
マリオネットのピットといえば、マリオネットのCollection View/CompossiteViewは他のView類の字面量を属性として伝えなければならないので、習慣的に使うと
PS 2
Backbone 1.0はもうlistenTo方法を提供しました.使ってもthisの問題がありません.また、公式サイトでは、ViewでlistenToを使用することを推奨しています.このようにViewのremove方法を起動すると、自動的にすべてのmodelを傍受することができます.メモリリークの原因となります.
面白いことに、私はUnderscoreのコードを調べてみましたが、元々はbindがnewオペレータと互換性があるかどうかについては、もう一回繰り返しました.興味がある人は見てもいいです.
https://github.com/jashkenas/underscore/commit/e6576cd83e82e8c2a4813eadd978a1abf6a69a79https://github.com/jashkenas/underscore/commit/ce3d1aec306999aa94926a42cad1daf7eb87a36f
アンロード・スコープ 私が大好きなJSライブラリです.先端の開発を簡単にするために、かなり便利なツールを提供しています.一番印象に残っています.好きな方法はbindAllです.たとえば:
var SomeUI = function(element) {
_.bindAll(this); $(element).click(this.doSomething);
}
SomeUI.prototype.doSomething = function() { this.doAnother() // ...}
ここでは、bindAllを通して、このコンポーネントのすべての方法が実行されるとき、thisは自分自身のインスタンスを指していることを確認し、コードの書き込みを簡略化することができます.その後、BackboneのViewを使う時、この方法は更に私の標準装備になりました.model事件のモニターコールバック関数はデフォルトではthisはmodel自身を指すので、3番目のパラメータを追加で伝達しないと変えられません.これは私など怠け者にはとても受け入れられないです.
var SomeView = Backbone.View.extend({ initialize : function () {
_.bindAll(this); this.model.on('change', this.render); this.model.on('xxx', this.xxx);
}
});
問題が発生するこのようないい日が長く続いています.私が使い始めるまで. マルオネット 穴に落ちて、やっと見つけました.
_.bindAll(this)
多くの予想外の問題を引き起こす.簡単のために、このコードを見てください.var Users = Backbone.Collection.extend({ model : User, initialize : function () {
_.bindAll(this);
}
});var users = new Users([
{name : 'xxx'}
]);
このコードはChromeなどの高級ブラウザで実行しても大丈夫ですが、IE 8でエラーが発生します.なぜですか?実はそのビッドオールに原因があります.原因分析
本来私たちはUsersクラスで定義された方法を自動bindで一回だけ見たいですが、重要な点を見逃しました.
model属性に対応するUserは実はfunctionなので、bindにも使われています. !
ああ、愚かですね.Javascriptには類がないです.functionだけです.
しかし、なぜIEの下でエラーが発生しました.Chromeの下で大丈夫ですか?なぜならbindの機能はECMAScript 5のFunction.prototype.bindと同じです.ChromeはECMAScript 5をサポートしていますので、この時はブラウザの元の方法を優先的に採用します.IE 8などの旧式のブラウザに対して、それは相応のfallbackを提供して実現します.MDNで調べてみました bindメソッドのドキュメント ,中には、bindによって過ぎたfunctionにnew操作符を使えば、thisは変わらないと述べています.残念なことに、Underscore 1.4.4里のfallbackは非常に簡単に実現され、newオペレータの問題を考慮していないので、悲劇になりました.
解決方法
はい、もうここに来ました.どうすればいいですか?Underscoreの新しいバージョンを確認しましたが、1.5.1の中のbindはもうこの問題を修復しました.newオペレータとよく協力できました.しかし、1.5.1はビッドオールの方法を重大に調整しました.
Removed the ability to call_.bindAll withのmethod name argments.It's pretty much always wiser to white-list the names of the methods you'd like to bind.
つまり、新バージョンはもうサポートされていません.
_.bindAll(this)
このように、ビッドを必要とするすべての方法名を明示的に指定しなければならない.ふふ、大根をもう一本ください.しかし、よく考えてみると、bindAllのこの修正はやはり道理があります. あなた自身が何が起こったのかよくわからないかもしれません.このように事故が発生しやすく、バグを解決するのが難しいので、パラメータを指定したほうがいいです.何時に補充しますか
PS 1
マリオネットのピットといえば、マリオネットのCollection View/CompossiteViewは他のView類の字面量を属性として伝えなければならないので、習慣的に使うと
_.bindAll(this)
問題を引き起こし、原理は上の誤りの例と同じである.PS 2
Backbone 1.0はもうlistenTo方法を提供しました.使ってもthisの問題がありません.また、公式サイトでは、ViewでlistenToを使用することを推奨しています.このようにViewのremove方法を起動すると、自動的にすべてのmodelを傍受することができます.メモリリークの原因となります.
var SomeView = Backbone.View.extend({ initialize : function () { // bindAll ,render this
this.listenTo(this.model, 'change', this.render);
}
});
PS 3面白いことに、私はUnderscoreのコードを調べてみましたが、元々はbindがnewオペレータと互換性があるかどうかについては、もう一回繰り返しました.興味がある人は見てもいいです.
https://github.com/jashkenas/underscore/commit/e6576cd83e82e8c2a4813eadd978a1abf6a69a79https://github.com/jashkenas/underscore/commit/ce3d1aec306999aa94926a42cad1daf7eb87a36f