バグのある JavaScript コードは、JavaScript 関数がどのように機能するかを実際には理解していない結果であることに何度も気づきました (ちなみに、私はそのコードの多くを書きました)。これは私たちの進歩の妨げになります
初心者として、関数呼び出しの 5 つのメソッドをテストしてみましょう。表面的には、これらの関数は C# の関数に非常に似ていると思われますが、すぐにわかります。依然として非常に重要な違いがあり、これらの違いを無視すると、追跡が困難なバグが発生することは間違いありません。まず、以下で使用する単純な関数を作成しましょう。この関数は、this と 2 つの指定されたパラメーターの現在の値のみを返します。
function makeArray(arg1, arg2)。 ){
return [ this, arg1, arg2 ];
}
最も一般的に使用されるメソッドですが、残念なことに、グローバル関数呼び出し Javascript を学ぶとき、上記の例の構文を使用して定義する方法を学びます。機能。また、この関数の呼び出しは非常に簡単であることもわかっています。必要なのは次のとおりです:
makeArray('one', 'two');
// => [ window, 'one', 'two' ]
ちょっと待って、そのウィンドウは何ですか
alert( typeof window.methodThatDoesntExist );
// => unknown
alert( typeof window.makeArray);
// =>
window.makeArray(' one ', 'two');
// => [ window, 'one', 'two' ]
最も一般的な呼び出しメソッドは、宣言した関数がデフォルトでグローバルになるため、残念だと言います。グローバル メンバーがプログラミングのベスト プラクティスではないことは誰もが知っています。これは JavaScript で特に当てはまります。 myFunction() などのオブジェクトから直接呼び出された場合、この値はデフォルトのオブジェクト (ブラウザーのウィンドウ) になります。
関数呼び出し 次に、メソッドの 1 つとして makeArray 関数を使用して、単純なオブジェクトを作成しましょう。json を使用してオブジェクトを宣言し、このメソッドも呼び出します
//オブジェクトの作成
var arrayMaker = {
someProperty: 'ここに何らかの値',
make: makeArray
};
//make() メソッドを呼び出します
arrayMaker.make('one', 'two');
// => one', 'two' ]
// 角括弧を使用した代替構文
arrayMaker['make']('one', 'two');
// [ arrayMaker, 'one', 'two' ]
ここで違いを見てください。 this の値はオブジェクト自体になります。なぜ元の関数定義が変更されていないのか、なぜウィンドウではないのか疑問に思うかもしれません。これが JavaScript で関数が渡される方法です。関数は標準のデータ型であり、関数全体をパラメータリストと関数本体とともにコピーして arrayMaker 属性 make に割り当てることができます。次のように arrayMaker を定義する場合:
var arrayMaker = {
someProperty: 'some value here',
make: function (arg1, arg2) {
};
JavaScript関数呼び出しルール2
メソッド呼び出し構文では、 obj.myFunction() または obj['myFunction']() の場合、この値は obj です
これはイベント処理コードのバグですメイン ソース、これらの例を確認してください www.2cto.com
最初のボタンをクリックすると、メソッド呼び出しであるため「btn」が表示され、これが属するオブジェクト (button 要素) であるため、2 番目のボタンをクリックすると、(obj.buttonClicked ( とは異なり) buttonClicked が直接呼び出されるため、「window」が表示されます。 ).) これは、イベント ハンドラー関数をラベルに直接配置する 3 番目のボタンと同じです。したがって、3 番目のボタンをクリックした結果は、jQuery のような JS ライブラリを使用すると次のような利点があります。イベント処理関数が jQuery で定義されている場合、JS ライブラリは this の値を書き換えて、現在のイベント ソース要素への参照が確実に含まれるようにします
//Use jQuery $('#btn1').click( function ( ) {alert( this.id ); // jQuery は 'this' がボタンになるようにします });
jQuery は this の値をどのようにオーバーロードしますか? 続きを読む
他の 2 つ: apply() と call() JavaScript 関数を使用すると、Qjuery がイベント ハンドラーで行うのと同じように、関数を渡して別のコンテキストで呼び出す必要があることがわかり、多くの場合、 this の値をリセットする必要があります。前に述べたことを覚えておいてください。関数もオブジェクトですJavascript では、関数オブジェクトにはいくつかの定義済みメソッドが含まれており、そのうちの 2 つは apply() と call() です。
var GasGuzzler = { year: 2008, model: 'Dodge Bailout' };
makeArray。 apply( GasGuzzler, [ 'one', 'two' ] );
// => [ GasGuzzler, 'one' , 'two' ]
makeArray.call( GasGuzzler, 'one', 'two' );
/ / => [ GasGuzzler, 'one' , 'two' ]
これら 2 つのメソッドは似ていますが、違いは次のパラメーターです。違いは、Function.apply() が関数に渡すために配列を使用するのに対し、Function.apply() は関数に渡すために配列を使用することです。実際には、ほとんどの場合、apply() の方が便利であることがわかります。
JSavacript 関数呼び出しルール 3
関数をメソッドにコピーせずに this の値をオーバーロードしたい場合は、次のようにします。 myFunction.apply(obj) または myFunction.call(obj) を使用できます。
Javascript の型のコンストラクター定義については詳しく説明しませんが、現時点では Javascript にはクラスが存在しないことを知っておく必要があります。カスタム型には初期化関数が必要です。プロトタイプ オブジェクトを (初期化関数のプロパティとして) 使用して Doctrine の型を定義することもお勧めします。 // コンストラクターを宣言します
function ArrayMaker(arg1) 、arg2){
this.someproperty = 'whatidhy'; 'one', 'two' );
var other = new ArrayMaker( 'first', 'first' );
am.getArray(); [am, 'one', 'two' ]
非常に重要で注目すべき点は、関数呼び出しの前に表示される new 演算子です。これがないと、関数はグローバル関数のようになり、作成するプロパティはグローバル オブジェクト (ウィンドウ) 上に作成されます。もう 1 つのトピックは、コンストラクターに戻り値がないため、new 演算子を使用するのを忘れると、変数の一部が未定義に割り当てられることです。このため、始めるのは良い習慣です。コンストラクター関数には大文字が付いています。これは、呼び出し時に以前の new 演算子を忘れないように注意するためのものであり、初期化関数のコードと他の言語で作成した初期化関数の値は似ています。
Javascript 関数呼び出しルール 4
MyFunction() のような関数を初期化関数として使用すると、JavaScript の実行により新しく作成されたオブジェクトに this の値が割り当てられます。さまざまな関数呼び出しの方法の違いにより、JavaScript コードがバグから遠ざけられます。その一部は、最初の段階でバグを回避するために this の値を常に把握できるようにします。