javascriptにおけるthisの指向問題
6859 ワード
本論文はjavascript設計モードと開発実践から抜粋し、thisの指向問題について.ブロガーの方がいいと思います.特にシェアしてください.一般的でないwithとevalを除いた場合、具体的には実際の応用において、thisの指向は大体以下の4種類に分けられます.を対象とする方法で呼び出します.を普通の関数として呼び出します.コンストラクタの呼び出し.Function.prototype.callまたはFuntions.prototype.appy呼び出し.オブジェクトとしての方法呼び出し関数をオブジェクトとしての方法で呼び出すと、thisはオブジェクトを指す: は、一般的な関数として、関数がオブジェクトの属性として呼び出されない場合、すなわち、一般的な関数として呼び出され、このときのthisは常にグローバルオブジェクトを指す.ブラウザのJavaScriptでは、このグローバルオブジェクトはwindowオブジェクトです. コンストラクタはJavaScriptにはクラスがないと呼び出しますが、コンストラクタからオブジェクトを作成することができます.また、new演算子を提供して、コンストラクタが1つのクラスに見えるようにします.宿主が提供するいくつかの内蔵関数を除いて、ほとんどのJavaScript関数はコンストラクタとして使用できます.コンストラクタの外観は普通の関数と同じで、それらの違いは呼び出された方式にあります.new演算子で関数を呼び出すと、この関数はいずれもオブジェクトに戻ります.通常、コンストラクタ内のthisは戻りのこのオブジェクトを指します.コードを参照してください. Function.prototype.callまたはFuntion.prototype.appy呼び出しは、通常の関数呼び出しと比較して、Funtion.prototype.callまたはFunction.prototype.appyで、着信関数のthisを動的に変更することができます.
var obj = {
a: 1,
getA: function(){
alert ( this === obj ); // :true
alert ( this.a ); // : 1
}
};
obj.getA();
window.name = 'globalName';
var getName = function(){
return this.name;
};
console.log( getName() ); // :globalName
:
window.name = 'globalName';
var myObject = {
name: 'sven',
getName: function(){
return this.name;
}
};
var getName = myObject.getName;
console.log( getName() ); // globalName
時々、divノードのイベント関数の内部で、一部のcalback方法があります.calbackは普通の関数として呼び出された時、calback内部のthisはwindowを指しましたが、私達はよくdivノードを指したいです.次のコードを参照してください.<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>
この時は簡単な解決策があります.divノードの参照は変数で保存できます.document.getElementById( 'div1' ).onclick = function(){
var that = this; // div
var callback = function(){
alert ( that.id ); // :'div1'
}
callback();
};
ECMAScript 5のstrictモードでは、この場合のthisは、グローバルオブジェクトではなく、undefinedを指すように規定されています.function func(){
"use strict"
alert ( this ); // :undefined
}
func();
var MyClass = function(){
this.name = 'sven';
};
var obj = new MyClass();
alert ( obj.name ); // :sven
しかし、newでコンストラクタを呼び出す時、もう一つの問題に注意しなければなりません.もしコンストラクタがobjectタイプのオブジェクトを明示的に返したら、今回の計算結果は最終的にこのオブジェクトに戻ります.var MyClass = function(){
this.name = 'sven';
return { //
name: 'anne'
}
};
var obj = new MyClass();
alert ( obj.name ); // :anne
コンストラクタが任意のデータを明示的に返さない場合、または非オブジェクトタイプのデータを返す場合、上記の問題は発生しません. this.name = 'sven'
return 'anne'; // string
};
var obj = new MyClass();
alert ( obj.name ); // :sven
var obj1 = {
name: 'sven',
getName: function(){
return this.name;
}
};
var obj2 = {
name: 'anne'
};
console.log( obj1.getName() ); // : sven
console.log( obj1.getName.call( obj2 ) ); // :anne