関数呼び出しのパターン、より正確には、選択されたパターンによって結果がどのように大きく変化するかを調べることをお勧めします。 また、関数の呼び出し方法に応じて、これがどのように動作するかを見ていきます。
したがって、関数を呼び出すには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つの機能があります。
- 関数が数値、チェーン、論理式(true / false)、nullまたはundefinedを
return
場合、return
は機能せず、this
を取得しthis
- 関数がオブジェクトの実装(つまり、単純な変数を除くすべて)を返す場合、このオブジェクトではなく、このオブジェクトが表示されます。
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
上記の例では、
this
は
null
(関数はオブジェクトではない)を参照しており、配列は
num1
と
num2
バインドされています。 しかし、最初のパラメーターで実験を続けましょう:
var obj = {
データ: 「Hello World」
}
var displayData = function ( ) {
警告 ( この .data ) ;
}
displayData ( ) ; //未定義
displayData。 適用 ( obj ) ; // Hello World
この例では、
apply
を使用して
this
を
obj
にバインドし
apply
。 その結果、
this.data
の値を取得できます。 applyの真価は、
this
をバインドすることにあります。
JavaScriptには、パラメーターではなく引数のリストを受け取ることを除いて、全員に
apply
call
ステートメントもあります。
おわりに
良くも悪くも、JavaScriptが世界を支配しようとしています。 したがって、その機能、特に避けるべき機能について知る必要があります。 JavaScript学習者にとって、4つの関数呼び出しパターンを理解することは必須です。 この投稿がお役に立てば幸いです。