JavaScriptの4つのパターンの関数呼び出し

JavaScriptは関数型プログラミング言語として導入されました。 その理由は、JSの関数はロジックを操作可能なブロックに分割するだけでなく、関数は他のオブジェクトを作成できる一流のオブジェクトだからです。 このような関数への依存は、この言語の強みであり、本当の呪いでもあります。 強力な点は、同様の機能を備えた言語が軽量かつ高速になることです(作成者が最初にJavaScriptを見たように)。 ただし、何をしているかわからない場合は、間違いなくトラブルが発生することを期待してください。

関数呼び出しのパターン、より正確には、選択されたパターンによって結果がどのように大きく変化するかを調べることをお勧めします。 また、関数の呼び出し方法に応じて、これがどのように動作するかを見ていきます。

したがって、関数を呼び出すには4つの方法があります。



関数実行


JavaScriptは、最新のすべての言語と同様に、関数内のロジックを調整できます。これらの関数は、実行中のプロセスの途中でいつでも呼び出すことができます。 関数を呼び出すことで、必要なパラメーターとプロセス制御を渡し、現在の操作を停止します。 呼び出し演算子は括弧()で 、コンマで区切られたパラメーターを囲むことができます。

残念ながら、関数を呼び出すためのパターンがいくつかあります。 それらを意識する必要はありません。 選択したパターンに応じて異なる結果が得られるため、それらを記憶して理解する必要があります。 私の意見では、この機能は言語自体の設計の誤りであり、JavaScriptをより短時間で、より注意して作成すれば、同様の性質のさまざまな問題を回避できます。

4つのパターン


既に述べたように、関数を呼び出すための演算子は1つであり、呼び出す方法は4つあります。

メソッド呼び出し-メソッド呼び出し

関数がオブジェクトの一部である場合、メソッドと呼ばれます。 「メソッド呼び出し」とは、オブジェクトに属する関数の呼び出しです。 例:

var obj = {
0
増分関数 {
これ + = 1 ;
}
} ;

obj。 インクリメント ;

「メソッド呼び出し」では、 this値は関数が属するオブジェクト(この場合はobj)を参照し、この接続は遅延バインディングという用語を含む関数の起動後に確立されます。

関数呼び出し-関数呼び出し

関数呼び出しは、演算子()を使用して実行されます。

追加 2、3 ; // 5

このパターンを使用して、グローバルオブジェクトにバインドします。 これは間違いなく言語の間違いです。これをグローバルオブジェクトに常にバインドすると、そのコンテキストが破壊される可能性があります。 これは、メソッド内で関数を使用する場合に特に顕著です。 例を見てみましょう:

var value = 500 ; //グローバル変数
var obj = {
0
増分 関数 {
これ ++;

var innerFunction = function {
アラート この ;
}

innerFunction ; //関数呼び出しパターン
}
}
obj。 インクリメント ; //メソッド呼び出しパターン

画面に何が表示されると思いますか? 1を決定した場合-あなたは間違っています(ただし、自分自身を非難しないでください-曲がったJavaScriptデザインを非難してください)。 正解は500ですinnerFunctionは前述の「関数呼び出し」パターンを使用して呼び出されるため、 thisグローバルオブジェクトにバインドされることに注意してください。 その結果、500になります。

this変数を作成することでこの問題を簡単に回避できますが、これはハックです。

var value = 500 ; //グローバル変数
var obj = {
0
増分 関数 {
var that = this ;
あれ。 ++;

var innerFunction = function {
アラート その ;
}

innerFunction ; //関数呼び出しパターン
}
}
obj。 インクリメント ;

したがって、 thisを関数が呼び出されるオブジェクトにバインドthisました。

コンストラクター呼び出し-コンストラクター呼び出し

警告:これは、従来のOOP言語とは非常に異なる別のJavaScript機能です! これはプロトタイプ指向のプログラミング言語ですが、作成者は「古典派」の人々(そのほとんど)が不快に感じるだろうと考えていました。 その結果、従来のOOPの原則がJavaScriptのプロトタイプに追加され、結果として混乱が生じました。

古典的なOOPでは、オブジェクトはクラスの実装です。 C ++およびJavaでは、このような実装にnew演算子が使用されます。 どうやら、JSの作成者はこの例に大きく遅れをとらず、「コンストラクター呼び出し」パターンで同様の何かを実装することに決めました...

パターンは、呼び出しの直前にnew演算子を配置することで開始されます。次に例を示します。

var Cheese = function type {
cheeseType = type ;
cheeseTypeを返します
}

チェダー= ニューチーズ "チェダー" ; //型ではなくオブジェクトを返します

Cheeseは機能的なオブジェクト(コードを消化できることを意味します)にもかかわらず、newを使用して関数を呼び出すことで新しいオブジェクトを作成しました。 this場合、これは新しく作成されたオブジェクトを参照し、 returnの動作が変更されます。 戻りといえば。 「コンストラクター呼び出し」での使用には、2つの機能があります。


var obj = {
データ 「Hello World」
}

var Func1 = function {
return obj ;
}

var Func2 = function {
return "私は単純型です" ;
}

var f1 = new Func1 ; // f1はオブジェクトに割り当てられます
var f2 = new Func2 ; // f2は新しいオブジェクトに割り当てられます

thisの使用を無視し、オブジェクトにリテラルを割り当てることができます。1つではない場合:このパターンに関連付けられているJavaScriptの作成者は、言語の重要な機能の1つです。 このパターンは直感的ではなく、さらに問題が頻繁に発生します。 ダグラス・クロックフォードは、この問題の解決策を提案しました。createメソッドで拡張オブジェクトを使用できます。 JavaScriptのバージョン1.8.5以降、 Object.createは完全に機能するツールであると報告できたことを嬉しく思います。

電話をかけると電話をかける-電話をかけると電話をかける

このパターンは、他のパターンよりもはるかに優れていると考えられています。 これにより、パラメーターを提供し、 thisを示すとともに、関数を手動で開始できます。 関数は本格的なオブジェクトであるため、JavaScriptのすべての関数はFunction.prototypeに関連付けられています。つまり、それらにメソッドを簡単に追加できます。

このパターンは2つのパラメーターを使用します。最初のパラメーターはthisアタッチされるオブジェクト、2番目のパラメーターはパラメーターに関連付けられた配列です。

var add = function num1 num2 {
num1 + num2を返し ます。
}

配列= [ 3、4 ] ;
追加します。 適用 null 配列 ; // 7

上記の例では、 thisnull (関数はオブジェクトではない)を参照しており、配列はnum1num2バインドされています。 しかし、最初のパラメーターで実験を続けましょう:

var obj = {
データ 「Hello World」
}

var displayData = function {
警告 この .data ;
}

displayData ; //未定義
displayData。 適用 obj ; // Hello World

この例では、 applyを使用してthisobjにバインドしapply 。 その結果、 this.dataの値を取得できます。 applyの真価は、 thisをバインドすることにあります。

JavaScriptには、パラメーターではなく引数のリストを受け取ることを除いて、全員にapply callステートメントもあります。

おわりに


良くも悪くも、JavaScriptが世界を支配しようとしています。 したがって、その機能、特に避けるべき機能について知る必要があります。 JavaScript学習者にとって、4つの関数呼び出しパターンを理解することは必須です。 この投稿がお役に立てば幸いです。

Source: https://habr.com/ru/post/J155815/


All Articles