ホームページ > ウェブフロントエンド > jsチュートリアル > プロトタイプ関数オブジェクト learning_prototype

プロトタイプ関数オブジェクト learning_prototype

WBOY
リリース: 2016-05-16 18:50:16
オリジナル
1180 人が閲覧しました

このオブジェクトは関数の拡張であり、最も重要なのはバインド メソッドです。プロトタイプは関数の 1 つの側面のみを問題とします。ラップ メソッドも非常に重要です。 Wrap メソッドを使用して、親クラスの同じ名前のメソッドを呼び出します。
argumentNames
bind
bindAsEventListener
curry
defer
lay
methodize
wrap

コードをコピー コードは次のとおりです:

//Object オブジェクトの extend メソッドを通じて関数プロトタイプを拡張します
Object.extend(Function.prototype, (function() {
var slide = Array.prototype.slice;
//配列に引数を追加し、配列を返します。内部メソッド
function update(array, args) {
var arrayLength = array.length , length = args.length;
while (length--) array[arrayLength length] = args[length];
return array;
}
//基本的には update メソッドと同じですが、異なります。受信パラメータ配列を変更し、新しい配列を返します。
function merge(array, args) {
array = slide.call(array, 0);
return update(array, args);
//関数のパラメータを配列にフォーマットし、return
function argumentNames() {
var names = this.toString().match(/^[s(]*function[^(]) *(([^)]*))/)[1]
.replace(///.*?[rn]|/*(?:.|[rn])*?*//g, ' ')
.replace(/s /g, '').split(',');

return names.length == 1 && !names[0] : names; 🎜>}
//実行関数のコンテキストをコンテキストにバインドします。
function binding(context) {
if (arguments.length < 2 && Object.isUnknown(arguments[0])) return this ;
var __method = this, args = slide.call(arguments, 1);
return function() {
var a = merge(args, argument);
return __method.apply(context) , a);
}
}
//基本的にバインドと同様、つまり、渡される最初のパラメータがイベント オブジェクトであることを確認します。
function bindingAsEventListener(context) {
var __method = this, args = slide.call(arguments, 1);
return function(event) {
var a = update([event || window.event], args);
return __method. apply( context, a);
}
}
//curry は数学者の名前です。以下の具体的な例を見るとわかります。
関数curry() {
if (!arguments.length) return this;
var __method = this, args = slide.call(arguments, 0);
return function() {
var a = merge(args, argument);
return __method.apply(this, a);
}
}
//window.setTimeout 関数の単純なカプセル化
関数遅延(タイムアウト) {
var __method = this, args = slide.call(arguments, 1);
timeout = timeout * 1000
return window.setTimeout(function() {
return __method.apply (__method, args) ;
}, timeout);
}
//delay(0.01) と同等
function defer() {
var args = update([0.01], argument );
return this.lay.apply(this, args);
}
//ラッパーを使用して、単純な AOP 関数を実装するために呼び出される関数をラップします
function Wrap(wrapper) {
var __method = this;
return function() {
var a = update([__method.bind(this)], argument);
return Wrapper.apply(this, a); 🎜>}
}
//着信呼び出しメソッドの最初のパラメータとして現在のコンテキストを表示します。
function methodize() {
if (this._methodized) return this._methodized;
var __method = this ;
return this._methodized = function() {
var a = update([this], argument);
return __method.apply(null, a);
}
//呼び出し可能な外部関数を返します
return {
argumentNames: argumentNames,
bind: binding,
bindAsEventListener: bindingAsEventListener,
curry:curry,
lay : 遅延、
defer: 遅延、
wrap: ラップ、
methodize: methodize
}
})());


update、merge メソッド:内部メソッドについては詳しく説明しません。

argumentNames メソッドは、基本的にソース コードを見ることで理解できます。

は、基本的に正規表現を使用してパラメータ リストを提案します。メソッド内でスペースといくつかの特殊文字を削除し、「,」を使用して分割し、最後にパラメータ配列を返します。最終的に names.length == 1 を返す条件の用途がわかりません。試してみましたが効果はありませんでした、何かご存知でしたら教えてください。例を見てみましょう:


コードをコピー
コードは次のとおりです: var fn = function(foo, bar) { return foo bar; //-> ['foo', 'bar'] Prototype.emptyFunction.argumentNames(); /-> []

bind メソッド:
まず、渡されるパラメータの数を決定します。少なくとも 1 つのコンテキスト パラメータを渡す必要があります。bind() メソッドが直接呼び出された場合、元の関数オブジェクトは次のようになります。戻ってきました。呼ばないのと同じです。
バインド メソッドのプロトタイプは次のとおりです:bind(thisObj[, arg...]) -> 関数。バインド メソッドでは、args 変数を使用してオプションのパラメータを続けることができます。最初のパラメータを除くすべてのパラメータを格納します: args = slide.call(arguments, 1); この文は、__method 変数を現在の関数に設定することを意味します。

コードをコピーします コードは次のとおりです:
var obj = {
name: ' 素敵なデモ',
fx: function() {alert(this.name) }
};
window.name = 'とても美しいウィンドウです!';
function runFx( f) { f(); }
//ここで、__method は obj.fx と同等です
var fx2 = obj.fx.bind(obj); ); //とても美しいウィンドウです!
runFx(fx2); //素晴らしいデモ
/*
runFx 関数内で f() を呼び出さない場合、obj を呼び出します。 fx() を外部で直接実行すると、結果は「素晴らしいデモ」になります。
実際、次のように書くと、 var f=obj.fx;f(); 'I am so beautiful window!' という結果も得られます。
上記の例を通して、コンテキストの概念を理解できるはずです。
obj.fx() //コンテキストは次のとおりです: obj
f(); //コンテキストは次のとおりです: window
コンテキストは実際には最後の '.' より前のオブジェクトであることがわかります。関数が直接呼び出された場合、コンテキストは window
*/


最後に、匿名関数が適用されます。コンテキストが返されます。
注: var a = merge(args, argument); の引数と args =lice.call(arguments, 1); の引数は異なります。例を見てみましょう:


コードをコピーします コードは次のとおりです:
var obj = {
name : '素晴らしいデモ',
fx: function() {
alert(this.name 'n' $A(arguments).joi(', ')); >}
};
//[1,2,3] ここは、slice.call(arguments, 1);
var fx2 = obj.fx.bind(obj, 1, 2) です。 , 3);
//[4,5] ここでは merge(args, argument);
fx2(4, 5) 内の引数を示します。// 適切な名前を警告します。 2, 3, 4 , 5"



bindAsEventListener メソッド:
このメソッドはバインドに似ています。主な違いは次の文です: var a = update([event || window.event] , args); バインドされた関数の最初のパラメーターが常にイベント オブジェクトであることを確認します。例を見てみましょう:


コードをコピーします
コードは次のとおりです: var obj = { name: '素晴らしいデモ' }; function handler(e) {
var data = $A(arguments)
alert(this.name); 'nその他の引数: ' data.join(', ')); }
handler.bindAsEventListener(obj, 1, 2, 3); ======= ===




カレーメソッド:

私は個人的に、このメソッドのヘルプドキュメントに示されている例は良くないと感じています。これは一目で明らかな別の例です:

コードをコピーします

コードは次のとおりです: var F=function(){alert(Array.prototype.slice.call(arguments,0) .join(' '))}; F.curry('I').curry('am').curry('never-online').curry('http://www.never-online. net')(); //私は決してオンラインではありません http://www.never-online.net

遅延メソッドと遅延メソッド:

基本的に、これは window.setTimeout の単純なカプセル化です。時間の単位は秒です。

コードをコピーします。

コードは次のとおりです: // タイムアウトをクリアします var id = Element.hide.lay(5, 'foo'); window.clearTimeout(id); ;

wrap メソッド:
元の関数を「ラップ」した関数を返します。
Function#wrap は、アスペクト指向プログラミングの本質を単一のメソッドに抽出し、簡単に構築できるようにします。
この文の意味は次のとおりです。 var a = update([__method.bind(this)], argument);ラップされた関数を最初のパラメーターとしてラッピング関数に追加します。例を見てください。
コードをコピーします コードは次のとおりです。

function Wrapper(){
alert('wrapped');
}
//ラッパーの前後で元の関数を呼び出すことができます。 AOP に少し似ていますか?
var Wrapper=wrapped.wrap(function(oldFunc,param){
//oldFunc()
alert(param);
oldFunc();
} );

//wrapper,wrapped
wrapper("wrapper");

メソッド:
関数を取得してラップします。別の関数では、呼び出し時に、
これを最初の引数として元の関数にプッシュします。
このメソッドは、メソッド化されるメソッドがメソッド化されているかどうかを最初にチェックし、内部変数 this._methodized を介してチェックします。
最後に、methodize 関数が返すものは実際には this._methodized です。
この文: var a = update([this], argument); これが元の関数の最初のパラメータとして渡されることがわかります。例を見るだけで理解できます:
コードをコピー コードは次のとおりです:

// ターゲット オブジェクトに対して操作
// を実行する単純な関数から始めます。
var fn = function(target, foo) { target.value = foo };
// オリジナルのメソッド
fn(object, 'bar');
object.value //-> 'bar'
//methodize を呼び出した後、最初のfn 関数のパラメータのターゲットはオブジェクトになります
object.fnMethodized = fn.methodize();
object.value //-> 'boom!' 🎜>
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート