其實,this的取值,分四種情況。我們來挨個看一下。
在此再強調一遍一個非常重要的知識點:在函數中this到底取何值,是在函數真正被調用執行的時候確定的,函數定義的時候確定不了。因為this的取值是執行上下文環境的一部分,每次調用函數,都會產生一個新的執行上下文環境。
情況1:構造函數
所謂構造函數就是用來new對象的函數。其實嚴格來說,所有的函數都可以new一個對象,但是有些函數的定義是為了new一個對象,而有些函數則不是。另外注意,構造函數的函數名第一個字母大寫(規則約定)。例如:Object、Array、Function等。
function Foo(){
this.name="劉慧玲";
this.age=18;
console.log(this);
}
Foo();
function Fn(){
this.name="caroly";
this.age=12;
console.log(this);
}
var f=new Fn();
console.log(f.name);
console.log(f.age);
以上代碼中,如果函數作為構造函數用,那么其中的this就代表它即將new出來的對象。
注意,以上僅限new Foo()的情況,即Foo函數作為構造函數的情況。如果直接調用Foo函數,而不是new Foo(),情況就大不一樣了。
情況2:函數作為對象的一個屬性
如果函數作為對象的一個屬性時,并且作為對象的一個屬性被調用時,函數中的this指向該對象。
var obj={
? x:10,
? fn:function(){
? console.log(this);
? console.log(this.x);
}
}
obj.fn();
以上代碼中,fn不僅作為一個對象的一個屬性,而且的確是作為對象的一個屬性被調用。結果this就是obj對象。
var obj={
x:10,
fn:function(){
console.log(this);
console.log(this.x);
}
}
var fn1= obj.fn;
fn1();
如上代碼,如果fn函數被賦值到了另一個變量中,并沒有作為obj的一個屬性被調用,那么this的值就是window,this.x為undefined。
情況3:函數用call或者apply調用
當一個函數被call和apply調用時,this的值就取傳入的對象的值。至于call和apply如何使用,不會的朋友可以去查查其他資料,本系列教程不做講解。
var obj={
x:10
};
var fn = function(){
console.log(this);
? ? console.log(this.x);
}
fn.call(obj);
情況4:全局 &調用普通函數
在全局環境下,this永遠是window,這個應該沒有非議。
console.log(this==window);//true
普通函數在調用時,其中的this也都是window。
var x = 10;
var fn = function(){
? console.log(this); ?//window
? console.log(this.x); ?//10
}
fn();
不過下面的情況需要注意一下:
var obj = {
x:10,
fn:function(){
? function f(){
console.log(this);//window
console.log(this.x);//undefined
}
f();
}
}
obj.fn();
函數f雖然是在obj.fn內部定義的,但是它仍然是一個普通的函數,this仍然指向window。