函数 | this指向

thist指向问题是非常重要的,主要有以下几种情况:

函数所处位置 this指向
全局函数且没有直接调用的对象 非严格模式下,this指向全局window或者global
严格模式下,this指向undefined
属性方法 this指向调用这个方法的对象
构造函数 this指向实例对象
属性方法 this指向调用这个方法的对象
定时器 this指向window
事件函数 this指向绑定这个事件的对象
call apply bind this指向第一个参数,若第一个参数是null,在非严格模式下,this指向window
箭头函数 this指向定义箭头函数的上下文

全局函数:window

1
2
3
4
5
function fn() {
console.log('全局函数this', this);
}

fn(); // 全局函数this window

属性方法:调用方法的对象

1
2
3
4
5
6
7
8
const person = {
name: 'Katrina',
sayHello() {
console.log('对象中的this', this);
},
};

person.sayHello(); // 对象中的this {name: 'Katrina', sayHello: f}

构造函数:实例对象

1
2
3
4
5
6
7
function Person(name, age) {
this.name = name;
this.age = age;
console.log('构造函数中的this', this)
}

const p1 = new Person('Katrina', 18); // Person {name: 'Katrina', age: 18}

定时器: window

1
2
3
4
5
6
7
8
9
10
11
12
function sayHello() {
setTimeout(function (){
console.log('定时器的this', this)
}, 0)
}

const person = {
name: 'Katrina',
sayHello,
};

person.sayHello(); // 定时器的this Window

解释:setTimeout()等同于window.setTimeout()

若要让定时器的this指向person对象,可以把定期器的函数改为箭头函数

1
2
3
4
5
6
7
8
9
10
11
12
function sayHello() {
setTimeout(() => {
console.log('定时器的this', this)
}, 0)
}

const person = {
name: 'Katrina',
sayHello,
};

person.sayHello(); // 定时器的this {name: 'Katrina', sayHello: f}

事件函数:绑定事件的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style>
.box{
width:300px;
height: 300px;
background-color:pink;
}
</style>
<body>
<div class = 'box'></div>
<script>
const box = document.getElementsByClassName('box')[0];
box.addEventListener('click', function() {
console.log('事件绑定函数的this', this); // 事件绑定函数的this <div class = 'box'></div>
})
</script>

call apply bind:指定的第一个参数

补课:函数 | call apply bind区别(含手写)

箭头函数: 定义箭头函数时的上下文

1
2
3
4
5
6
7
8
9
10
window.color = 'red';
let o = {
color: 'green',
};

let sayColor = () => console.log(this.color); // 箭头函数的this引用定义时的上下文,此时是window

sayColor(); // red
o.sayColor = sayColor;
o.sayColor(); // res

在事件回调或定时回调中调用某个函数时,this 值指向的并非想要的对象,此时将回调函数写成箭头函数就可以解决问题

这是因为箭头函数中的this 会保留定义该函数时的上下文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function King() {
this.royaltyName = 'Henry';
// this 引用King 的实例
setTimeout(() => console.log(this.royaltyName), 1000);
}

function Queen() {
this.royaltyName = 'Elizabeth';
// this 引用window 对象
setTimeout(function() { console.log(this.royaltyName); }, 1000);
}

new King(); // Henry
new Queen(); // undefined