JavaScript設計モードの二:this、callとappy
5562 ワード
(本節の内容は:Javascriptデザインモードと開発実践の本から抜粋し、自分のノートとして保存し、必要な友達に役立つようにしたい)
this、callとappyはJavascriptプログラミングの中で応用がとても広いです.だから、私達は先にそれらを理解しなければなりません.
一、this
Javascriptの中のthisはいつも一つのオブジェクトを指していますが、それは環境動的バインディングを実行することに基づいています.以下の4つのケースは分析に用いられます.
関数をオブジェクトとする方法では、thisがオブジェクトを指し、次のコードを参照してください.
この問題をどう解決しますか?変数を使ってdivノードの参照を保存できます.
二、callとappy
以下では、コールとapplyを分析します.それらはES 3がFunctionのプロトタイプで定義されている2つの方法です.それらの役割は同じです.
appryは2つのパラメータを受け入れて、最初の指定関数の体内のthisオブジェクトの指向、二つ目は集合であり、配列であっても良いし、クラス配列であっても良いし、appy方法はセットの要素をパラメータとして呼び出しられた関数に伝達します.
applyまたはcallを使う時、最初のパラメータがnullを使うと、関数の体内のthisはデフォルトの宿主オブジェクトを指し、ブラウザの中でwindowですが、厳しいモードでは依然としてnullです.
アプリとコールの実際的な用途を見てみましょう.
1、thisの向きを変える
実際に開発された中で発生する可能性のある例を見てみます.例えば、ページにはdiv 1というIDのブロックがあります.
ほとんどのブラウザが内蔵Funtions.prototype.bindを実現し、関数内部のthis指向を指定します.(この内容はなぜ書くか分かりませんので、省略します.)
3、他のオブジェクトを借りる方法
借用方法の第一のシーンは「構造関数を借りる」ことによっていくつかの類似した継承効果が得られます.
this、callとappyはJavascriptプログラミングの中で応用がとても広いです.だから、私達は先にそれらを理解しなければなりません.
一、this
Javascriptの中のthisはいつも一つのオブジェクトを指していますが、それは環境動的バインディングを実行することに基づいています.以下の4つのケースは分析に用いられます.
関数をオブジェクトとする方法では、thisがオブジェクトを指し、次のコードを参照してください.
var obj = {
a: 1,
getA: function(){
alert(this === obj); //true
alert(this.a); //1
}
};
obj.getA();
通常の関数として呼び出されると、このときのthisは常にグローバルオブジェクトwindowを指します.window.name = 'globalName';
var getName = function(){
return this.name;
};
console.log(getName()); //globalName
次の実際的な例を示します.私達は一つのdivノードの内部で、一つの局部のcalback方法を定義します.この方法が普通の関数として呼び出されると、calback内部のthisはwindowを指します.以下のコードです.<html>
<body>
<div id="div1"> Div</div>
</body>
<script>
window.id = 'window';
document.getElementById('div1').onclick = function(){
alert(this.id); //div1
var callback = function(){
alert(this.id); //window
}
callback();
};
</script>
</html>
calback関数をそれぞれalert(this==calback)とalert(this==window)と書いてテストします.この問題をどう解決しますか?変数を使ってdivノードの参照を保存できます.
<html>
<body>
<div id="div1"> Div</div>
</body>
<script>
window.id = 'window';
document.getElementById('div1').onclick = function(){
var that = this;
alert(that.id); //div1
var callback = function(){
alert(that.id); //div1
}
callback();
};
</script>
</html>
ES 5のstrictモードでは、このようなthisはもうwindowを指しません.undefinedです.function func(){
"use strict";
alert(this); //undefined
}
func();
コンストラクタの呼び出しは、new演算子を使って関数を呼び出すと、いずれもオブジェクトに戻ります.コンストラクタ内のthisはこのオブジェクトを指します.var myClass = function(){
this.name = 'Kaindy';
};
var obj = new myClass();
alert(obj.name); //Kaindy
Function.prototype.callまたはFuntions.prototype.apply呼び出しは、着信関数のthisを動的に変えることができます.var obj1 = {
name: 'Kaindy',
getName: function(){
return this.name;
}
};
var obj2 = {
name: 'anne';
}
console.log(obj1.getName()); //Kaindy
console.log(obj1.getName.call(obj2)); //anne
OKです.次の例を見てみます.失われたthis:var obj = {
myName: 'Kaindy',
getName: function(){
return this.myName;
}
};
console.log(obj.getName()); //Kaindy
var getName2 = obj.getName;
console.log(getName2()); //undefined
Objがその方法をget Nameと呼ぶと、このときのthisはObjオブジェクトを指すので、ObjオブジェクトのmyName属性値をプリントし、オブジェクトObjのgetNameメソッドをオブジェクトget Name 2に値付けすると、このときは通常関数呼び出しであり、thisはグローバルwindowオブジェクトを指すので、undefinedを印刷します.二、callとappy
以下では、コールとapplyを分析します.それらはES 3がFunctionのプロトタイプで定義されている2つの方法です.それらの役割は同じです.
appryは2つのパラメータを受け入れて、最初の指定関数の体内のthisオブジェクトの指向、二つ目は集合であり、配列であっても良いし、クラス配列であっても良いし、appy方法はセットの要素をパラメータとして呼び出しられた関数に伝達します.
var func = function(a, b, c){
alert([a, b, c]); //[1, 2, 3]
};
func.apply(null, [1, 2, 3]);
callから入ってきたパラメータは固定されていません.最初のパラメータはappyと同じです.関数の体の中のthisの方向を表しています.二つ目のパラメータから、各パラメータは順次関数に導入されます.var func = function(a, b, c){
alert([a, b, c]); //[1, 2, 3]
};
func.call(null, 1, 2, 3);
Javascriptの内部では、パラメータは配列で表されています.だから、applyはcallの使用率よりも高いです.パラメータの数を明確にして、一目で表す形が参席の対応関係に参加したいなら、callを使います.applyまたはcallを使う時、最初のパラメータがnullを使うと、関数の体内のthisはデフォルトの宿主オブジェクトを指し、ブラウザの中でwindowですが、厳しいモードでは依然としてnullです.
アプリとコールの実際的な用途を見てみましょう.
1、thisの向きを変える
var obj1 = {
name: 'sven';
};
var obj2 = {
name: 'anne';
};
window.name = 'window';
var getName = function(){
alert(this.name);
};
getName(); //window
getName.call(obj1); //sven
getName.call(obj2); //anne
get Name.call(obj 1)を実行すると、get Name()関数の体内のthisがobj 1のオブジェクトを指します.実際に開発された中で発生する可能性のある例を見てみます.例えば、ページにはdiv 1というIDのブロックがあります.
document.getElementById('div1').onclick = function(){
alert(this.id); // this document.getElementById('div1') , div1
var func = function(){
alert(this.id); // this window , undefined
};
func();
}
上のコードの中で、イベント関数には内部関数funcがあります.この関数を呼び出すと、thisはwindowを指します.私たちはコールでそれを修正できます.document.getElementById('div1').onclick = function(){
alert(this.id); //div1
var func = function(){
alert(this.id); //div1
};
func.call(this);
}
2、Function.prototype.bindほとんどのブラウザが内蔵Funtions.prototype.bindを実現し、関数内部のthis指向を指定します.(この内容はなぜ書くか分かりませんので、省略します.)
3、他のオブジェクトを借りる方法
借用方法の第一のシーンは「構造関数を借りる」ことによっていくつかの類似した継承効果が得られます.
var A = function(name){
this.name = name;
};
var B = function(){
A.apply(this, arguments);
};
B.prototype.getName = function(){
return this.name;
};
var b = new B('sven');
console.log(b.getName()); //sven
第二のシーンは関数のパラメータリストargmentsを操作します.argmentsは本物の配列ではありません.argmentsに要素を追加したいなら、Aray.prototype.push方法を借りることができます.(function(){
Array.prototpye.push.call(argumets, 3);
console.log(arguments); [1,2,3]
})(1, 2);