ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript の衝突防止 [翻訳]_javascript スキル

JavaScript の衝突防止 [翻訳]_javascript スキル

WBOY
WBOYオリジナル
2016-05-16 17:49:531037ブラウズ

この記事では、主に JavaScript でこれをキュレーションおよびコア解除する方法について説明します。このトピックは ツイート からのものです。

1. この
アンカリングとは、次のシグネチャを持つメソッドを変換することを意味します:

obj.foo(arg1, arg2) を別のメソッドに変換する 次のシグネチャを持つ関数:

foo (obj, arg1, arg2) これの使い方を知りたい場合は、まず一般的なメソッドを理解する必要があります。


2. 一般的なメソッド (ジェネリック メソッド)

通常、特定のメソッドは特定のタイプのオブジェクト インスタンスでのみ使用できますが、他のタイプのオブジェクト インスタンスでも使用できるメソッドがいくつかあります。その場合、たとえば次のようになります。 🎜>

// 実際の実装の簡易バージョン:
Array.prototype.forEach = function (callback) {
for(var i=0; iif (i in this) {
callback(this[i] , i);
}
}
};
これは、forEach() メソッドの暗黙的なパラメーターと見なすことができ、次の 3 つのルールを満たすオブジェクトは forEach() メソッドを呼び出すことができ、暗黙的な this:
として使用できます。
•長さ属性を持つ: this.length
•インデックスによってオブジェクト要素にアクセスする機能: this[i]
•属性の存在をチェックする機能: this

arguments オブジェクト内の i ( function 呼び出しのすべての実パラメータは Array インスタンスではないため、forEach() メソッドを直接呼び出すことはできませんが、オブジェクトが forEach() メソッドを呼び出すための 3 つの条件を満たしています。幸いなことに、すべての関数には、何かを実行できる call() メソッドがあります:




コードをコピー

コードは次のとおりです。function printArgs() { Array .prototype.forEach.call(arguments, function (elem, Index) { console.log(index ". " elem);
});
}


forEach .call( ) には forEach() メソッドよりも 1 つ多くのパラメータがあります。最初のパラメータは指定された次の値です:



コードをコピー
コードは次のとおりです:> printArgs("a", "b")0. a1.b

があります。 JavaScript のいくつかの類似したメソッド 一般的なメソッドはこの方法で呼び出すことができ、これらのメソッドのほとんどは Array.prototype.
から取得されます。

3. アンチコリーのいくつかの使用法

使用例 1: map() を介してメソッドを呼び出す Array.prototype.map() メソッドを使用すると、配列内の各要素に対して関数を呼び出すことができます。しかし、関数の代わりにメソッドを呼び出したい場合はどうすればよいでしょうか。 ? はい これを行うには衝突防止を使用します:

コードをコピーします

コードは次のとおりです: > var toUpperCase = String.prototype.toUpperCase.uncurryThis();> [ "foo", "bar", "baz" ].map(toUpperCase)[ 'FOO', 'BAR ', 'BAZ' ]

使用例 2: 一般的なメソッドを関数に変換する。例:

のように、これをデカリングして関数に変換します。

コードをコピー
コードは次のとおりです:Array.forEach = Array.prototype.forEach.uncurryThis();function printArgs( ) { Array.forEach(arguments, function (elem, Index) {
console.log(index ". " elem);
});
}


ECMAScript 仕様の推奨事項の将来のバージョンには、すでに多くの同様の
配列メソッド
があります。
翻訳者注: Firefox はすでに

Array.forEach などを実装しています。メソッド.
4. uncurryThis() の実装 Array.map次に、uncurryThis メソッドを実装する 3 つの方法を示します。<br><br>実装 1: Brendan Eich によって作成されました。 <strong><br></strong><br>コードをコピーします<br><br><div class="codetitle"> コードは次のとおりです。<span><a style="CURSOR: pointer" data="60855" class="copybut" id="copybut60855" onclick="doCopy('code60855')"> <u>Function.prototype.uncurryThis = function () { </u>var f = this; </a>return function () { </span>var a = 引数; </div>return f.apply(a[0], [].slice.call(a, 1)); >};<div class="codebody" id="code60855">};<br>実装 2: アンチカリー化関数の呼び出しは、元のメソッドでその call() メソッドを呼び出すことと同じです。この call() メソッドを、bind() メソッドを通じて借用できます。 <br><div class="codetitle">コードをコピー<span><a style="CURSOR: pointer" data="87558" class="copybut" id="copybut87558" onclick="doCopy('code87558')"><u> コードは次のとおりです。</u></a> </span>Function.prototype.uncurryThis = function () { </div>この呼び出しを返します。 binding(this); <div class="codebody" id="code87558">}; <br><br> <br>実装 3: 定義された標準メソッドは、あまり多くの外部メソッドに依存しないことが最善です。また、bind() メソッドは ECMAScript でのみ使用できます。 5 .そこで、上記の実装 2 を次のように書き直しました: <br> </div> <br><br><br><div class="codetitle">コードをコピー <span><a style="CURSOR: pointer" data="7449" class="copybut" id="copybut7449" onclick="doCopy('code7449')"><u> コードは次のとおりです: </u> </a> </span>Function.prototype.uncurryThis = function () { </div>var f = this; <div class="codebody" id="code7449">return function () { <br>return f.call.apply(f, argument) <br>} ; <br>}; <br><br> <br>上記のコードは、暗黙的に <br> </div> <br> メソッドを借用しています。これを修正してください。 ><br>uncurryThis() の逆の操作は、curryThis() と呼ばれます。元の関数がある場合、元の関数の最初のパラメータを暗黙の this パラメータに変換します: <br><strong><br></strong>コードをコピーします<br><div class="codetitle"> <span> コードは次のとおりです。<a style="CURSOR: pointer" data="74336" class="copybut" id="copybut74336" onclick="doCopy('code74336')"><u> </u>function(self, arg) { </a>return self.foo arg </span> } </div> <div class="codebody" id="code74336"> <br>これをカリー化すると、次のようになります: <br><br><br> </div> <br>コードをコピーします<br><div class="codetitle"> <span> コードは次のとおりです:<a style="CURSOR: pointer" data="73673" class="copybut" id="copybut73673" onclick="doCopy('code73673')"><u> </u>function(arg) { </a>return this.foo arg; </span>} </div> <div class="codebody" id="code73673"> <br>使用例: メソッドがその this 値を埋め込み関数に渡します。元の書き込み: <br><br><br> </div> <br> コードをコピー <br><div class="codetitle"> <span> コードは次のとおりです: <a style="CURSOR: pointer" data="49106" class="copybut" id="copybut49106" onclick="doCopy('code49106')"><u></u>var obj = {</a> メソッド : function (arg) {</span> var self = this // ネストされた関数に this にアクセスさせます</div> someFunction(..., function() {<div class="codebody" id="code49106"> var self = this; // ネストされた関数にアクセスさせますfunction access this<br> });<br> },<br> otherMethod: function (arg) { ... }<br>}<br><br><br>カリー化した後、次のように書くことができます。 <br><br> <br> </div> <br>コードをコピー<br><div class="codetitle"> <span> コードは次のとおりです。<a style="CURSOR: pointer" data="22807" class="copybut" id="copybut22807" onclick="doCopy('code22807')"><u></u>var obj = {</a> メソッド: function(self、arg){//追加のパラメーター `self` </span>🎜> othermethod:function(arg){...}</div>} <div class="codebody" id="code22807"> <br><br>つまり、動的変数 self を静的変数 self に変換します。これを常に明示的パラメーターとして使用すると、JavaScript がより簡単になります。<br> <br>curryThis() の実装:<br><br><br><br><br>コードをコピー</div> <br> コードは次のとおりです:<p><br></p> <div class="codetitle">関数.prototype.curryThis = function () {<span> var f = this;<a style="CURSOR: pointer" data="75145" class="copybut" id="copybut75145" onclick="doCopy('code75145')"> return function () {<u> var a = Array.prototype.slice.call(arguments);</u> a.unshift(this );</a> return f.apply(null, a);</span> };</div>};<div class="codebody" id="code75145"> <br><br> <br><br>6. 関数プロトタイプを拡張したくない場合 <br><br> <br>上記で実装されたメソッドはすべて、組み込みコンストラクター Function() のプロトタイプに追加されており、独立した関数として簡単に書き換えることができます。<br><br> </div> <p>コードをコピーします<strong></strong></p> コードは次のとおりです:<p></p> <div class="codebody" id="code18130"> <br>function uncurryThis(f) {<br> return function () {<br> return f.call.apply(f, argument)<br> };<br>}<br>functioncurryThis(f ) {<br> return function () {<br> var a = Array.prototype.slice.call(arguments);<br> a.unshift(this);<br> return f.apply(null, a); <br> };<br>}<br> </div> <p><strong>7. 既存の信頼できないコードで uncurryThis() を安全に使用する </strong></p> <p>Mark Miller<tt>例として uncurryThis() を説明しました</tt>"<a href="http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming" target="_blank">安全なメタプログラミング</a>":<br><br>翻訳者注: これをカリー化することは関数を変換することです 最初のパラメータは変換されますこれをメソッド内で this にデカリーすることは、メソッド内の this を関数の最初のパラメーターに変換することです。</p> </div>
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。