深入理解JS:this是什么?

154 阅读3分钟

学习笔记,见证成长!

第一次码字写东西,欢迎大神们指教!

this是什么?

定义

this就是函数上下文,函数上下文就是this,即是函数调用时与其相关联的对象。

  • 第一:跟函数有关
  • 第二:跟函数调用有关(函数调用!!!谁调用了!!!

具体场景this的指向,往往由函数的调用方式来决定this具体指向是谁。

此外,还可能是由函数的定义方法决定,这里说的就是箭头函数的情况,后面将具体讨论。

函数调用方式

我们将函数调用方式分为5种:

  1. 函数直接被调用
  2. 函数作为属性方法调用
  3. 作为构造函数调用
  4. 通过call和apply方法调用
  5. 通过bind方法调用

- 函数直接被调用

示例展示了三种函数直接被调用的方式,均是在全局环境调用的,此时this就是window对象,严格模式下,this就是undefined。

//1、函数声明定义函数,直接在全局调用
function add(){
  console.log(this)
}
add()//window对象

//2、通过表达式定义函数,直接在全局调用
const sum = function(){
  console.log(this)
}
sum();//window对象

//3、立即执行函数
(function(){
  console.log(this) //window对象
})()

//严格模式
function useStrictFn(){
    "use strict"
    console.log(this)
}
useStrictFn();//undefined

- 函数作为属性方法调用

作为一个对象的方法被调用,此时this就是该对象。

const person = {
    name:function(){
        console.log(this)
    }
}
person.name();//getname对象

- 作为构造函数调用

构造函数是用于创建一个对象,当通过new关键字进行调用时,此时的this就是创建的实例对象。

function Student(name,age){
    this.name = name
    this.age = age
    console.log(this)
}
const zhangsan = new Student('zhangsan', 101); 
//Student{name: 'zhangsan',age:101} 
//Student的实例对象zhangsan

- 通过call和apply方法调用

call和apply能够改变this的指向,此时的this就是两个函数的第一个参数。两函数的唯一区别就是:call依次传参,apply数组形式传参。 call(this, ...params); apply(this, [...params])

function who(){
    console.log(this)
}
const zhangsan = {name: 'zhangsan'}
const lisi = {name: 'lisi'}
//对比:在全局直接调用是window对象
who();// window对象
who.call(zhangsan); // {name: 'zhangsan'}
who.apply(lisi) //{name: 'lisi'}

- 通过bind函数调用

通过bind函数也能改变this指向,此时this的指向也是第一个参数。bind函数的作用是,新创建一个函数,该函数的函数体与原函数一样,返回新创建的函数。传参形式与call函数的相同

function who(){
    console.log(this)
}
const zhangsan = {name: 'zhangsan'}
//定义变量接收返回的新函数
const newFunc = who.bind(zhangsan);
newFunc();//{name: 'zhangsan'}

箭头函数中的this指向

箭头函数没有单独的this的指向,箭头函数中的this由函数创建定义时决定。

//全局环境以对象字面量的方式创建对象
//此时箭头函数的this都指向window对象
//此时this与函数在哪调用无关
const person = {
    name:() => {
        console.log(this)
    },
    child: {
        childName:() => {
            console.log(this)
        }
    }
}
person.name();//window对象
person.child.childName() //window对象

总结

this是指函数上下文,即与函数关联的对象。

this具体指向,与函数的调用方式和定义方式(箭头函数)有关。

函数调用方式由5种:直接调用fn()、作为方法obj.fn()、构造函数new Fn()、call和apply、bind

箭头函数没有单独的this指向,它的this指向与箭头函数在哪创建定义有关。