this指向问题

概要

  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指向问题 1.1 认识词法作用域 其实我们js中的作用域就是词法作用域,我们会发现词法作用域最重要的特征是...
    心存美好阅读 145评论 0 0
  • 日期:2019 年 9 月 5 日 this 指向问题 介绍 this 指向问题一直是 js 中一个令人头疼的问题...
    五十岚色叶阅读 348评论 0 3
  • 1. this指向问题 1.1 认识词法作用域 其实我们js中的作用域就是词法作用域,我们会发现词法作用域最重要的...
    时光如剑阅读 971评论 0 8
  • this指向 1.默认绑定 什么情况下使用默认绑定呢?独立函数调用。 独立的函数调用我们可以理解成函数没有被绑定到...
    落墨诗卷阅读 390评论 0 3
  • this是我们日常最经常使用的语法之一。通过这篇文章分析一下this的指向问题。说到this就一分为二来看(ES6...
    慕时_木雨凡阅读 416评论 0 0