關於this,首先要知道this的是在代碼執行的時候才能確定的,定義的時候不能確定,因爲this是執行上下文的一部分,而執行上下文是在代執行的時候才能確定的。實際上this的最終指向的是那個調用它的對象。
想理解this先看幾個例子:
var a = {
name:'A',
fn: funcrion(){
console.log(this.name);
console.log(this);
}
}
a.fn(); //this.name === 'A'; this===a
a.fn.call({name:'B'}); //this.name===='B'; this==={name:'B'}
var fn1 = a.fn;
fn1(); //this.name === undefined; this===window
通過上面的例子可以看出this的執行會有不同,主要集中在以下幾種情況:
1.作爲構造函數執行,在構造函數中(上面例子未體現)
2.作爲對象屬性執行,上述代碼中的a.fn();
3.作爲普通函數執行,上述代碼中fn1();
4.用於call,apply,bind,上述代碼中a.fn.call({name:’B’});
其中fn1() 的執行結果有些出乎意料,上文說過‘實際上this的最終指向的是那個調用它的對象’,fn1中this爲什麼指向了window?繼續來看例子:
function a() {
var user = "例子";
console.log(this.user); //undefined
console.log(this); //window
}
a();
按照我們上面說的this最終指向的是調用它的對象,這裏的函數a實際是被Window對象所點出來的,下面的代碼就可以證明:
function a() {
var user = "例子";
console.log(this.user); //undefined
console.log(this); //window
}
window.a();
繼續看例子:
var o = {
user: "例子",
fn: function(){
console.log(this.user); //'例子'
console.log(this); // o
}
}
o.fn(); ==>window.o.fn()
o.fn();等價於window.o.fn(),但是this並沒有指向window,而是指向O對象;是不是有些迷惑,繼續看例子:
var o = {
a = 10;
b : {
a:12;
fn:function(){
console.log(this.a); //12
console.log(this); //b
}
}
}
o.b.fn();
同樣屬性都是對象o調用出來的,但同樣this沒有指向O。其實我們需要知道以下幾點:
1.如果一個函數中有this,但是沒有被上一級對象調用,那麼this就指向window,嚴格模式下t’his將指向undefined;
2.如果一個函數中有this,這個函數被上一級對象調用,那麼this指向上一級對象;
3.如果函數中有this,這個函數中包含多個對象,儘管這個函數是被最外層的對象所調用,this指向的也是其上一級對象。(上面的例子中,將b對象的值註銷既可以驗證)
var o = {
a = 10;
b : {
//a:12;
fn:function(){
console.log(this.a); //undefined
console.log(this); //b
}
}
}
o.b.fn();
還有個特殊的例子:
var o = {
a = 10;
b : {
a:12;
fn:function(){
console.log(this.a); //undefined
console.log(this); //window;
}
}
}
var c = o.b.fn;
c();
this指向的是最後調用它的對象,也就是看它執行的時候是誰調用的,這個例子中雖然函數fn是被對象b所引用,但是在將fn賦值給變量c的時候並沒有執行所以最終指向的是window。
在構造函數中this指向也會不同:
function Fn(){
this.user = '例子';
}
var a = new Fn();
console.log(a.user) //'例子'
這裏a可以調用到user的值,因爲構造函數new關鍵字改變了this的指向,所以將this指向a。
當this遇到return時結果也會有差異,如下面的連個例子:
function Fn(){
this.user = '例子';
return {};
}
var a = new Fn();
console.log(a.user) //undefined
function Fn(){
this.user = '例子';
return 1;
}
var a = new Fn();
console.log(a.user) //'例子'