我們都知道,調用一個函數一共有四種調用模式:
-
方法調用模式
- 定義:當一個函數被保存為對象的一個屬性的時候,這個函數被稱為方法。
- 此時的this:當一個方法被調用的時候,this綁定到該對象上。
-
舉例子:
var obj = {
name:"harrisking",
foo: function(){
console.log(this.name);//harrisking
//這里的this指的就是obj;
}
}
-
函數調用模式
- 定義:當一個函數并非一個對象的屬性時,則這個函數就是一個函數來調用的。
- 此時的this:以此模式調用函數時,this被綁定到全局對象(window)。
-
舉例子:
var a = function(){
console.log(this.b())
}
var b = function(){
console.log("馬達,又躺槍!")
}
a();//"馬達,又躺槍!"
構造器調用模式
-
定義:如果一個函數前面帶上一個new來調用,則該函數就是作為構造函數來調用的。
- 這里要補充一個重要的知識點——new到底做了些啥?
當一個構造函數前加上new的時候,背地里來做了四件事:
1,生成一個空的對象并將其作為 this;
2,將空對象的proto 指向構造函數;
3,運行該構造函數;
4,如果構造函數沒有 return 或者 return 一個返回 this 值是基本類型,則返回
this;如果 return 一個引用類型,則返回這個引用類型。
- 這里要補充一個重要的知識點——new到底做了些啥?
此時的this:這時候,this被綁定到了新構造的對象上。
舉例子:
var People = function(name,age){
this.name = name;
this.age = age;
};
var p1 = new People('harrisking',23);
p1.name;//harrisking;apply調用模式
定義:apply和call的方法很像,它擁有兩個參數:一個是預設定的this,一個是要傳遞的參數(apply傳遞的是數組)。
分割線
敬愛的方方老師推薦的方法是:
將上述四種調用方式還原為call/apply形式。
則:
- 方法調用模式:
obj.foo( ) ==> obj.foo.call('obj');則this就是obj; - 函數調用模式:
a() ==> window.a.call() ==> 因為call未指定this的值,則這里的this代表window;
最后特此感謝方方老師的原文 this的值到底是什么