this代表了函數(shù)運行時,是函數(shù)運行上下文
純函數(shù)調(diào)用,此時this指向全局對象global
const x = 1;
global.x = 2;
function hello() {
const x = 3;
console.log(this.x);
}
hello();//2
作為構(gòu)造函數(shù)調(diào)用,此時this指向new出來的實例對象
const x = 1;
global.x = 2;
function Hello() {
this.x = 3;
this.hello = function () {
console.log(this.x);
}
}
new Hello().hello();//3
作為對象方法調(diào)用,此時this指向該對象
const x = 1;
global.x = 2;
function hello() {
console.log(this.x);
}
const o = {};
o.x=4;
o.hello = hello;
o.hello.call({x:6});
call、apply調(diào)用,運行時改變函數(shù)上下文環(huán)境,即改變this指向;第一個參數(shù)都是指定this指向的環(huán)境,call接受依次參數(shù),apply接收參數(shù)偽數(shù)組;
const apple = {color: 'red'}, banana = {color: 'yellow'};
function sayYourColor() {
this.color = 'default';
this.say = function (oo) {
console.log(`my color is ${this.color}, oo is ${oo}`);
}
}
const fruit = new sayYourColor();
fruit.say('a');//my color is default, oo is a
fruit.say.call(apple, 'b');//my color is red, oo is b
fruit.say.apply(banana, ['c']);//my color is yellow, oo is c
bind和箭頭函數(shù),只有第一次bind會生效;箭頭函數(shù)定義時會綁定父環(huán)境中的this,不會運行時動態(tài)變化,即使bind也無法改變
function setTimeOutSelf() {
this.x = 'self';
this.out1 = function () {
setTimeout(function () {
console.log(`this.x -> ${this.x}`);
}, 1000)
};
this.out2 = function () {
setTimeout(function () {
console.log(`this.x -> ${this.x}`);
}.bind({x:'out'}).bind(this), 1000);
};
this.out3 = function () {
setTimeout((()=> {
console.log(`this.x -> ${this.x}`);
}).bind({x:'out'}), 1000)
}
}
const TOS=new setTimeOutSelf();
TOS.out1();//this.x -> undefined
TOS.out2();//this.x -> out
TOS.out3();//this.x -> self
bind 是返回對應函數(shù);apply 、call 則是立即調(diào)用。
JS 每一個 function 有自己獨立的運行上下文,而箭頭函數(shù)不屬于普通的 function,所以沒有獨立的上下文。所以在箭頭函數(shù)里寫的 this 其實是包含該箭頭函數(shù)最近的一個 function 上下文中的 this(如果沒有最近的 function,就是全局)