美文网首页js
this指向问题

this指向问题

作者: 蓝蓝红同学 | 来源:发表于2022-06-28 16:17 被阅读0次

    概要

    1. 为什么使用this?
    2. this指向什么?
    3. this绑定规则
    4. this案例理解

    为什么使用this

    在某些函数和方法的编写中,this指向可以让我们更加便捷的方式来引用对象。在某些api的设计中,代码更加简洁和易复用

    比如当我们调用一个对象中的属性,可通过obj.key来实现,但如果我们修改了对象名则内部所有调用修需要修改。

    例子:代码中我们需要修改对象名obj为info时,内部函数中的所有obj都需修改为info

    所以我们需要使用this来解决这个问题,修改对象名不影响对象内部函数的调用

    this指向什么

    首先全局作用域中,this在浏览器测试中指向window

    但实际开发中,this的使用一般是在函数中调用

    js函数在执行时,会创建一个执行上下文。这个执行上下文记载函数的调用栈、调用方式、传参等等,this也是其中一个重要的属性。

    例子:当我们定义一个函数,使用三种方式调用

    • 函数在调用时,JavaScript会默认给this绑定一个值
    • this的绑定和定义的位置没有关系
    • this的绑定和调用方式以及调用的位置有关系
    • this是在运行时被绑定的

    this绑定规则

    默认绑定

    默认绑定,一般用于独立函数

    • 独立函数直接调用
    • 调用链,所有函数的this都没有绑定到某个对象上
    • 将函数作为参数传入

    foo()的调用是将整个函数作为函数传入foo,所以函数调用是在独立函数中,this指向全局

    foo3()的调用的入参是obj.foo1(),所以入参已经是调用后的函数,foo1函数的调用是在obj中实现的,this指向obj对象

    隐式绑定

    通过某个对象调用,即****它的调用位置中,是通过某个对象发起的函数调用

    • 通过对象调用
    • 对象obj2调用对象obj1再调用函数,函数实际调用位置在obj1上
    • 隐式丢失

    将obj1.foo赋给bar时并未对函数进行调用,函数的调用是在bar中进行,此时this指向window

    显式绑定

    隐式绑定中,需要对象自身拥有一个对应的属性。

    • call和apply

    当我们在对象中没用定义这个属性,但又需要这个对象来调用函数时,我们需要用到call/apply方法来实现

    1. call和apply都是Function原型上的方法
    2. 两个方法的功能类似,都是让调用函数的this绑定到特定的对象上
    3. 两个方法第一个参数都是接收要绑定的对象,第二个参数为函数入参,call为参数列表,apply为参数数组

    call和apply显式绑定

    • bind函数

    当我们需要将一个函数始终绑定到一个对象上时

    • 使用bind写一个辅助函数

    此时的bar函数调用时,this指向始终与obj对象绑定

    • 使用Function.prototype.bind
    • 内置函数

    当我们使用JavaScript的一些内置函数或者第三方库的内置函数时,这些函数要求我们传入另一个函数,我们并不会显式调用这些函数,而JavaScript或者第三方库会帮助我们执行,这些函数的this时如何绑定的呢?

    • setTimeout

    setTimeout传入的函数的this指向window

    • 数组forEach

    直接调用时,函数的this指向window

    forEach方法的第二个参数可接收要执行改方法的数组,传入第二个参数后可将this的指向绑定到传入的数组上

    new绑定

    new关键字来调用一个函数时,会进行以下操作:

    1. 创建一个新的对象
    2. 将对象的原型指向构造函数的prototype(此时this指针完成绑定)
    3. 执行构造函数
    4. 返回对象

    规则优先级

    • 首先默认规则的优先级最低,即默认绑定等
    • 显式绑定的优先级高于隐式绑定
    • new绑定的优先级高于显示绑定

    即优先级:new绑定>显式绑定>隐式绑定>默认绑定

    特殊的this指向

    • 忽略显式绑定

    在显式绑定时,如果传入一个null或者undefined,则这个显式绑定会被忽略,使用默认规则

    • 间接函数引用

    赋值obj2.foo = obj1.foo结果为foo函数,被直接调用则为window

    • 箭头函数

    es6中新增的箭头函数不使用this绑定的规则,而是根据外层作用域来决定this

    this引用会在上层作用域中查找对应的this

    案例理解

    • 案例一
    • 案例二
    • 案例三

    相关文章

      网友评论

        本文标题:this指向问题

        本文链接:https://www.haomeiwen.com/subject/ieztbrtx.html