用一句話總結this的指向:this是在調用函數的時候,根據執行上下文所動態決定 。
應用場景一:當函數自然執行的時候,this是undefined或者window;例如
function myFunction() {
console.log('this', this);
}
myFunction()
//這種如果使用嚴格模式,則this是undefined
應用場景二:函數被別人調用的時 (被人誰 點.出來,this就是誰)
function myFunction() {
console.log('this', this); //this是a對象
}
var a = {
b: myFunction
};
a.b();
案例1:下面案例的this是指誰呢?
var father = {
name: 'father',
son: {
name: 'son',
buy: function () {
console.log('this', this);
}
}
};
father.son.buy();
答案是son,函數前面有多少個點都不用管,只管裏執行時函數最近的那個點前面是誰,那麼this就是誰,當然,用apply/call/bind除外
案例2:
<script>
var father = {
name: 'father',
buy: function () {
console.log('this', this);
}
};
var son = {
name: 'son'
}
son.buy = father.buy;
son.buy()// 這個時候this就是son
</script>
案例3:
var father = {
name: 'father',
buy: function () {
console.log('this', this);
}
};
var son = {
name: 'son'
}
son.buy = father.buy;
var allbuy = son.buy;
allbuy();
顯然上面的this是window,函數執行時;
案例4:
var father = {
name: 'father',
buy: function () {
console.log('this', this);
}
};
var son = {
name: 'son'
}
son.buy = father.buy;
// window.addEventListener('scroll', son.buy); // 這裏的this就是window,
// 還有一個案例
var a = (1,2); // 這裏涉及逗號表達式,這裏a的值是2,返回後一個值,
(1, son.buy)(); // ==> var b = (1, son.buy); b() b執行,執行的時候,this是window
案例5:
function Person(params) {
this.buy = function () {
console.log('this', this);
}
}
var xiaoming = new Person('xiaoming')
var xiaohong = {};
xiaohong.buy = xiaoming.buy;
xiaohong.buy();// 這個時候,this就是xiaohong,看執行時是誰
應用場景三:new一個實例時
function Person(name) {
this.name = name;
console.log(this); // 使用new創建對象,這個時候this就是新創建的對象
}
var xiaoming = new Person('xiaoming');
應用場景四:apply、call、bind時
function getColor(params) {
this.color = params;
console.log(this);
}
function Car(name, color) {
this.name = name;
getColor(color).call(this);// 這裏把this把原來的變成了Car的shilling對象
}
var lanbojini = new Car('lanbojini', 'black');
call和apply的區別,可以這樣記:call,打電話得一個一個打,apply可以一起打,或者“取長補短”
bind並非立即執行,bind不會改變原函數,它會返回來一個函數,返回來的這個函數執行,纔是用bind改變了this的函數
如果某個函數已經被bind過了,再次用.去調用,那麼規則2就不適用了:
var sonbuy = buy.bind(xiaoxiao);
father.sonbuy(); 這個時候,this任然是xiaoxiao,而不是father
應用場景五:箭頭函數的this指向由離箭頭函數最近的非箭頭函數的執行上下文決定(定義時)也就是:定義時離我最近的非箭頭函數的上下文是啥,我就是啥;
function outerWrap(params) {
console.log('外層函數this', this);
const outer = () => {
console.log('outer this', this);
}
function innerCall() {
console.log('innerCall', this); // 這裏的this是window
outer();
}
innerCall();
}
var wife = {
name: 'wife'
}
wife.outer = outerWrap;
wife.outer();
那麼箭頭函數認call和apply擺佈this嗎?