13

私はオープン ソースの JavaScript ライブラリを作成しています.bind()が、メソッドを多用しています。これは、オブジェクト指向のコードがより明確に見えるという考えがあるためです。(議論の余地はありますが

A1:

var that = this;

setTimeout(function () {
    that.method();
}, 0);

B1:

setTimeout(this.method.bind(this), 0);

または、より実用的なコード部分

A2:

remoteDataSource.getData(function (a, b, c, d) {
     obj.dataGetter(a, b, c, d);
})

対 B2:

remoteDataSource.getData(obj/* or prototype */.dataGetter.bind(obj));

古いブラウザーには非ネイティブを使用していますが、 bind の jsperf ベンチマークbindを開くまではすべてが完璧でした。

コードを使用するbindと 100 倍遅くなるようです。ライブラリをすべて書き直す前に、javascript エンジンに詳しい方に質問があります。

新しい機能であるbindため、すぐに最適化される可能性はありますか、それとも JavaScript アーキテクチャの制限のために可能性はありませんか?

4

2 に答える 2

14

まず、jsperf http://jsperf.com/bind-vs-emulate/13を修正しました。

=ベンチマーク内で静的関数を再作成しないでください。実際のコードでは静的関数は一度しか作成されないため、これは現実的ではありません。

var self = thisパターンがまだ約 60% 高速であることがわかります。ただし、どこからでもバインドできるため、保守性が向上するため、関数定義をインライン化する必要があります。


いいえ、組み込みのバインド セマンティクスは途方もなく複雑です。

私がバインドするとき、私はこれが欲しいだけです:

function bind(fn, ctx) {
    return function bound() {
        return fn.apply(ctx, arguments);
    };
}

引数を事前に適用したり、深いコンストラクターの黒魔術を使用したりしたい場合は、まったく別の関数が必要です。なぜこれがバインドに含まれていたのか、私にはわかりません。

<rant>ところで、同じ問題は ES5 で導入されたほとんどすべてのものにあり、実際には誰にももっともらしく関係のない理論的なエッジ ケースを処理するよう実装に強制することで、一般的なケースを罰します。次の言語バージョンも同じ道をたどっています.</rant>

エミュレートされたバインドは、バインドをエミュレートしようとさえしません。そして、それをエミュレートしようとしても、完全にはできないので、それは公正ではありません。

したがって、他のすべてが等しい*場合、組み込みのバインドは、バインドするだけの常識的なカスタムバインドよりも高速になることはありません。

*JIT では、ユーザー コードは組み込みコードに比べて大きな欠点はありません。実際、SM と V8 は両方とも Javascript で多くのビルトインを実装しています。

于 2013-09-20T05:46:48.193 に答える
0

現在、2013 年後半の最善の解決策は、 の手作りバージョンを実装Function.prototype.bindし、ベンダーの「ネイティブ」(真のネイティブではない) メソッドを独自の JavaScript コードでオーバーライドするか、独自の を使用することmyBindです。

Function.prototype.applyはかなり高速で、配列のスライス、連結、およびシフトは遅いため、apply代わりに ifbindを使用するか、関数内の引数操作を最小限に抑えますmyBind。これにより、パラメーターの事前入力の機能がなくなります。

したがって、すべてをクロージャーに書き直す必要はありません(醜いvar that = this;)。JavaScript の機能的な性質を勝ち取りましょう。

詳細と実際のコード例はこちら:

http://jsperf.com/function-bind-performance/4

http://jsperf.com/function-bind-performance/5

http://jsperf.com/bind-vs-emulate/4 .. 10.

要約: 見つかった回避策はそれほど悪くありません。それらを勇敢に使用してください。完全に機能していない を使用する場合はbind、元の概念から離れすぎないでください。C で実装されていない理由はまだ見つかっていません。時間の問題です。

于 2013-09-19T13:51:31.433 に答える