this,call,apply到底是個什麼東西
this
this可以分為全域性的this, 和 函式內的this。全域性的this毫無疑問指向window物件。而函式內的this,是隨著函式的執行環境進行變化的。程式碼如下
// 全域性this
console.log(this)//window
//函式內的this
function test(){
console.log(this)
}
test()//打印出window因為test()函式在全域性呼叫
this的指向如何變化
this 的指向隨著函式執行環境而變化。
當函式作為物件的方法呼叫時,this 指向該物件。
var obj = {
a: 1,
getA: function(){
alert ( this === obj );
// 輸出:true
} };
當函式作為普通函式呼叫時,this 指向全域性window物件。
function test(){
console.log(this)
}
test() // 打印出 window 因為test()函式在全域性呼叫
當函式作為建構函式呼叫時,this指向這個物件。
建構函式的外 表跟普通函式一模一樣,它們的區別在於被呼叫的方式。當用 new 運算子呼叫函式時,該函式總 會返回一個物件,通常情況下,構造器裡的 this 就指向返回的這個物件,見如下程式碼:
varMyClass=function(){
this.name='sven';
};
varobj=newMyClass();alert(obj.name);
// 輸出:sven
但是,如果建構函式返回了另外一個物件,則裡面的this就會指向這個返回的物件。
varMyClass=function(){
this.name='sven';
return{
name:'anne'
}
};
var obj = new MyClass();
alert(obj.name);
// 輸出:anne
Function.prototype.call 或 Function.prototype.apply 呼叫。
用 Function.prototype.call 或 Function.prototype.apply 可以動態地 改變傳入函式的 this:
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
call apply 是個什麼???
都知道call,apply可以用來改變this的指向,但是這個說法太書面了,不好理解。其實call,apply是Function原型物件上的兩個方法。他可以隱式的給一個物件新增一個方法,並且預設執行這個方法。比如上面的程式碼中obj1.getName.call( obj2 )實際上給物件obj2添加了obj1的getName()方法,所以最終輸出anne。
說的再通俗一點,其實是把obj1 的getName方法,作為obj2的方法直接執行了。
call和apply的區別
call apply的作用一樣,區別僅在於引數形式不一樣。
func.apply(null,[1,2,3]);//第二個引數 為陣列或類陣列
func.call(null,1,2,3); // 第二個引數 依次傳入
搞清楚這些以後,就可以愉快的理解一些高階函式。
關注我一起回憶《javaScript高階程式設計》《javaScript設計模式中》你沒注意過的細節