文章目录
前言
很多JS初学者第一次接触this的时候,很容易被他的指向搞晕。我当时也不例外,现在回过头来记录一下this指向的有关案例。
ES5
在es5中,我们可以简单的理解this的指向规律为:谁执行或者是谁的就指向谁。
在全局作用域中
function fn() {
console.log(this)
}
fn() // 执行打印window,因为我们的函数是定义在全局作用域中,也就是把变量定义在window上,作为属性,所以函数调用其实就是window在调用这个函数,this指向这个函数。
在对象上
let obj = {
showThis(){
console.log(this)
}
}
obj.showThis() // 打印obj,一样原理,因为函数是obj上身的,也是obj执行的,所以就指向obj
好,很自信是不是,给你来个坑
let obj = {
showThis(){
setTimeOut(function(){console.log(this)},0)
}
}
obj.showThis() // 先猜下
// 打印的是window,因为setTimeOut筛入的函数的执行是setTimeOut执行的,学过setTimeOut的都知道,setTimeOut是window上的函数,所以打印出来的是window。
那想打印正确的this指向怎么办呢?可以借助es6的箭头函数。
ES6箭头函数
es6的箭头函数this指向当前环境,且是固定的。
引用我之前写箭头函数的文章的话就是:
let obj = {
showThis(){
setTimeOut(()=>{console.log(this)},0)
}
}
obj.showThis() // 因为箭头函数的this指向环境,此时这个环境就是showThis内,showThis又是obj的,所以this指向obj。
其实对环境这个词觉得抽象的话,可以理解为指向上个作用域即可。
class类中
class Person {
constructor(name) {
this.name = name
}
showThis(){
console.log(this)
}
}
const man = new Person('小夏')
man.showThis() // this指向当前对象 man
改变this指向
主要是三剑客:call、apply、bind
function fn() {
console.log(this)
}
fn.call({a: 1}) // 打印this为{a: 1}
可以看到call就是改变指向的同时执行函数。call的第二个参数是fn的入参,例如fn.call(null, 1, 2)
const fn1 = fn.bind({a: 1})
fn1() // 打印this为{a: 1}
可以看出,bind改变this指向,并返回改变指向后的函数,还需要自己亲自执行。bind的第二个参数是fn的入参,例如bind.call(null, 1, 2)()
apply的用法和call一样,只不过第二个参数传的是数组,例如:fn.apply(null, [1, 2])