JavaScript、5種類の関数を呼び出す方法


JavaScript、5種類の関数を呼び出す方法
この文章はJavascriptの中の各種の関数の呼び出しの方法とその原理を詳しく紹介して、JavaScriptの関数を理解することに対してとても大きい助けがあります!
何度も、バグのあるJavascriptコードは、Javascript関数がどのように機能しているかを本当に理解していないためであることに気づきました(ちなみに、多くのコードは私が書いたものです).JavaScriptは関数式プログラミングの特性を持っていて、私たちがそれに直面することを選んだとき、これは私たちの前進の障害になります.初心者として、5つの関数呼び出しの方法をテストします.表面から見ると、それらの関数はC#の関数と非常に似ていると思いますが、後で非常に重要な違いが見られます.これらの違いを無視すると、追跡しにくいバグを招くに違いありません.
まず、以下で使用する簡単な関数を作成します.この関数は、現在のthisの値と2つのパラメータのみを返します.
<script type="text/javascript">
function makeArray(arg1, arg2){
    return [ this, arg1, arg2 ];
}
</script>

最も一般的な方法ですが、残念ながらグローバルな関数呼び出しJavascriptを学習すると、上記の例の構文で関数を定義する方法がわかります.この関数を呼び出すのは非常に簡単であることも知っています.
makeArray('one', 'two');
// => [ window, 'one', 'two' ]

Wait a minute. What's that window object doing there? Why is it the value of this? If you haven't stopped to think about it, please stay with me here.ちょっと待って、あのWindowオブジェクトはここで何をしているのか、なぜthisの値がそれなのか、もしあなたが以前この問題を考えていなかったら、私と一緒に分析してください.Javascriptでは、私は特定のブラウザを指していません.グローバルなオブジェクトがあります.あなたのスクリプトに散らばっているように見えるコード(たとえば、オブジェクトの外にある宣言)は、グローバルオブジェクトのコンテキストに書かれています.私たちの例では、そのmakeArray関数は緩やかなグローバル関数ではなく、グローバルオブジェクトの方法と言えるので、ブラウザに戻ってみましょう.この環境では、そのグローバルオブジェクトがwindowオブジェクトにマッピングされています.証明しましょう
alert( typeof window.methodThatDoesntExist );
// => undefined
alert( typeof window.makeArray);
// => function

これらのすべては、makeArrayを呼び出す前の方法が次の方法と同じであることを意味します.
window.makeArray('one', 'two');
// => [ window, 'one', 'two' ]

最も一般的な呼び出し方法は不幸なことに、私たちが宣言した関数のデフォルトがグローバルであるためだと言います.グローバルメンバーはプログラミングのベストプラクティスではないことを知っています.これはJavaScriptの中で特に正確で、JavaScriptの中でグローバルなメンバーを使うことを避けて、あなたは後悔しません.
JavaScript関数呼び出しルール1所有者オブジェクトを明示せずに直接呼び出された関数、例えばmyFunction()では、thisの値がデフォルトオブジェクト(ブラウザ内のウィンドウ)になります.
関数呼び出しは簡単なオブジェクトを作成し、makeArray関数をその方法として使用し、jsonを使用してオブジェクトを宣言し、この方法を呼び出します.
//creating the object
var arrayMaker = {
    someProperty: 'some value here',
    make: makeArray
};

//invoke the make() method
arrayMaker.make('one', 'two');
// => [ arrayMaker, 'one', 'two' ]
// alternative syntax, using square brackets
arrayMaker['make']('one', 'two');
// => [ arrayMaker, 'one', 'two' ]

ここの違いを見て、thisの値はオブジェクトそのものになりました.元の関数の定義が変わっていないのに、なぜwindowではないのか疑問に思うかもしれません.これがJsabacriptで関数を渡す方法ですJavaScriptでは標準的なデータ型で、正確にはオブジェクトです.彼らを伝えたりコピーしたりすることができます関数連帯パラメータのリストと関数体全体がコピーされ、arrayMakerのプロパティmakeに割り当てられているように、arrayMakerを定義します.
var arrayMaker = {
    someProperty: 'some value here',
    make: function (arg1, arg2) {
        return [ this, arg1, arg2 ];
    }
};

JavaScript関数呼び出しルール2 objのようなメソッドを使用して構文を呼び出す.myFunction()またはobj['myFunction']()の場合、thisの値はobj
これはイベント処理コードのバグの主なソースです.これらの例を見てください.
<input type="button" value="Button 1" id="btn1"  />
<input type="button" value="Button 2" id="btn2"  />
<input type="button" value="Button 3" id="btn3"  onclick="buttonClicked();"/>
<script type="text/javascript">
function buttonClicked(){
    var text = (this === window) ? 'window' : this.id;
    alert( text );
}
var button1 = document.getElementById('btn1');
var button2 = document.getElementById('btn2');

button1.onclick = buttonClicked;
button2.onclick = function(){   buttonClicked();   };
</script>

最初のボタンをクリックすると「btn」が表示されます.これはメソッド呼び出しであるため、thisは所属するオブジェクト(ボタン要素)に対して2番目のボタンをクリックすると「window」が表示されます.buttonClickedは直接呼び出されます(obj.buttonClicked()とは異なります.)これは私たちの3番目のボタンと同じで、イベント処理関数を直接ラベルに入れるのと同じです.だから3番目のボタンをクリックした結果は2番目と同じでした.jQueryのようなJSライブラリを使用すると、jQueryでイベント処理関数を定義すると、JSライブラリは、現在のイベントソース要素の参照が含まれていることを保証するためにthisの値を書き換えるのに役立ちます.
//  jQuery
$('#btn1').click( function() {
    alert( this.id ); // jQuery ensures 'this' will be the button
});

jQueryはどのようにしてthisの値を再ロードしますか?読み続ける
他の2つ:apply()とcall()JavaScriptの関数を使用するほど、関数を伝達し、異なるコンテキストで呼び出す必要があることがわかります.Qjueryがイベント処理関数でやったように、thisの値をリセットする必要があります.Javascriptでは関数もオブジェクトであり、関数オブジェクトにはapply()とcall()の2つの事前定義された方法が含まれています.これらを使用してthisをリセットすることができます.
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.call()はこれらのパラメータを独立して伝達し、実際にはapply()が多くの場合便利であることがわかります.
Jsabacript関数呼び出しルール3関数をメソッドにコピーせずにthisの値を再ロードしたい場合はmyFunctionを使用します.apply(obj)またはmyFunction.call( obj ).
コンストラクタJavascriptでのタイプの定義を深く研究したくありませんが、Javascriptにはクラスがないことを知る必要があります.また、カスタムタイプには初期化関数が必要です.プロトタイプオブジェクト(初期化関数の属性として)を使用してあなたのタイプを定義するのも良い主義です.簡単なタイプを作成しましょう.
//       
function ArrayMaker(arg1, arg2) {
    this.someProperty = 'whatever';
    this.theArray = [ this, arg1, arg2 ];
}
//        
ArrayMaker.prototype = {
    someMethod: function () {
        alert( 'someMethod called');
    },
    getArray: function () {
        return this.theArray;
    }
};

var am = new ArrayMaker( 'one', 'two' );
var other = new ArrayMaker( 'first', 'second' );

am.getArray();
// => [ am, 'one' , 'two' ]

1つは非常に重要で注意に値するのは、関数呼び出しの前に現れるnew演算子です.それがなければ、あなたの関数はグローバル関数のように、私たちが作成した属性はグローバルオブジェクトに作成されますが、そうは思いません.もう1つの話題は、あなたのコンストラクタに値が戻っていないので、new演算子を使用するのを忘れたら、いくつかの変数がundefinedに割り当てられます.このため、コンストラクタ関数は大文字で始まるのが良い習慣で、呼び出し時に前のnew演算子を忘れないように注意することができます.このような注意を持って、初期化関数の中のコードはあなたが他の言語で書いた初期化関数と似ています.この値はあなたが作成するオブジェクトです.
Javascript関数呼び出しルール4関数を初期化関数として使用する場合、MyFunction()のようにJavascriptの実行時にthisの値を新しいオブジェクトとして指定します.
まとめて、私はあなたのSjavacriptコードをbugsから遠ざけることができる様々な関数の呼び出し方法の違いを理解したいと思っています.このようなbugの中には、thisの値が彼らを避けるための最初のステップであることを常に知っているものもあります.
原文:http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx訳者:ルーク