一、什麼是this、this又指向誰?
1.1 什麼是this
定義:this是包含它的函數作爲方法被調用時所屬的對象。這句話聽起來有點繞嘴,但一個多餘的字也沒有,定義非常準確,我們可以分3部分來理解它!
1、包含它的函數。
2、作爲方法被調用時。
3、所屬的對象
1.2 this指向誰
誰最終調用函數,this就指向誰。
二、this指向特點
1、this指向的只可能是對象。
2、this指向誰,不取決於this寫在哪兒,而取決於函數在哪兒調用。
3、this指向的對象,稱之爲函數的上下文(函數的調用者)。
1、直接調用
直接調用函數,this
指向window。
function fn() {
var a = 1;
console.log(this); // window
console.log(this.a); // 2
}
var a = 2;
fn();
2. 對象的形式調用
在對象上調用函數,this
指向調用的那個對象。
function xx() {
var a = 1;
console.log( this); // obj ====> ({a: 3, xx: ƒ})
console.log(this.a); // 3
}
var a = 2;
var obj = {
a: 3,
xx: xx,
};
obj.xx();
3. 構造函數(new操作符)
在構造函數中 this
永遠綁定在fn
上,也就是說他指向new
出來的那個對象,this
不會發生改變。
function Fn() {
var a = 1;
console.log(this); // Fn {}
console.log(this.a); // undefined
}
var a = 2;
var fn = new Fn();
4. 定時器(匿名函數)調用
定時器函數作爲window
內置函數的回調函數調用,其調用的是window.setTimeout
,此時的this
指向window
。
var a = 1;
setTimeout(function () {
var a = 2;
console.log(this); // window
console.log(this.a); // 1
}, 1000);
5. 在箭頭函數中調用
學過ES6都知道箭頭函數本身其實是沒有this
和arguments
的,實際上箭頭函數中的this
取決於包裹着箭頭函數的第一層普通函數的this
,大白話就是離他最近的父級函數,來看一個例子:
function ft() {
var a = 1;
return () => {
console.log(this); // window
console.log(this.a); // 2
};
}
var a = 2;
ft()();
由上面的例子不難看出,包裹着箭頭函數的第一個普通函數是ft
函數,由於ft
函數指向window
,即在箭頭函數中調用this
指向window
6. call、apply、bind
call
、apply
、bind
這些改變上下文的函數其this
指向取決於第一個參數。如果第一個參數爲''
、null
、undefined
等,則this
指向window
;如果傳遞的有參數則this
指向第一個參數。
首先看不傳參數時的情況:
function ff() {
var a = 1;
console.log(this);
console.log(this.a);
}
var obj = {
a: 3,
};
var a = 2;
ff.call(); // window 2
ff.apply(); // window 2
var ff1 = ff.bind() // window 2
ff1()
然後給他們傳遞參數時的情況:
function ff() {
var a = 1;
console.log(this);
console.log(this.a);
}
var obj = {
a: 3,
};
var a = 2;
ff.call(obj); // obj ====> { a: 3 } // 3
ff.apply(obj); // obj ====> { a: 3 } // 3
var ff2 = ff.bind(obj); // obj ====> { a: 3 } // 3
ff2();