可能是最好的 this 解析了…

释放双眼,带上耳机,听听看~!

今天我们就来啃下这个你可能害怕但又不得不去吃的瓜,this !

找对象

首先, this 在大多数情况下是一个对象,也有可能是 undefined 或其他值

什么情况下,this 是 undefined ?函数运行在严格模式下,应用默认绑定规则的时候:

原理其实很简单,因为规范定义了严格模式下,不能将全局对象 Window 用于默认绑定。而大多数情况下,我们说的 this,其实就是一个对象,所以确定 this 的指向,本质上就是要找到这个对象

所以接下来我就来教大家如何 “找对象” 🤣 。

绑定规则

找对象最重要的是什么?是不是得先通过各种途径(社交,搭讪,相亲…)去认识对象,途径越多,我们找到对象的几率就越大,对吧,这里也是一样,所以我们需要尽可能的了解 this 的绑定规则。

ECMAScript 5规范[1] 定义的 this 的绑定规则,有 4 种。

默认绑定

教科书会告诉我们,几乎所有的规则都会有一个默认的情况,this 绑定也不例外,默认绑定的规则为:

非严格模式下,this 指向全局对象,严格模式下,this 会绑定到 undefined

隐式绑定

如果函数在调用位置有上下文对象,this 就会隐式地绑定到这个对象上

说起来有点晦涩,直接看例子:

这个规则可能会让你想起关于 this 经常听到的一句话,this 依赖于调用函数前的对象

需要注意的是,隐式绑定在某些情况下可能会导致绑定丢失,具体来说有两种情况,

第一种是使用函数别名调用时:

第二种是函数作为参数传递时:

显式绑定

我们知道 callapplybind 等方法可以改变 this 的指向,通过传入参数就可以指定 this 的绑定值,够不够显式 ?这种明目张胆的绑定 this 的规则就叫显式绑定。

call 和 apply 的区别只是接受的参数格式不同,call 接受一个参数列表,apply 接受一个参数数组,但两者的第一个参数都是相同的,都是 绑定的 this 值

前文我们提到隐式绑定可能会导致绑定丢失,显式绑定也不例外,

思考一下,如何才能解决绑定丢失的问题?

答案其实很简单,只需要在调用函数的内部使用显式绑定,强制地将 this 绑定到对象:

这其实就是 bind 的实现原理,与 callapply 不同,bind 调用后不会执行,而是会返回一个硬绑定的函数,所以通过 bind 可以解决绑定丢失的问题。bind 也是显式绑定,我们来回顾下 bind 的用法:

此外,需要注意的是,将 nullundefined 作为第一个参数传入 callapplybind ,调用时会被忽略,实际应用的是默认绑定规则,即严格模式下,this 为 undefined,非严格模式下为全局对象。

new绑定

先来回顾下 new 的实现原理,

了解了原理,我们不难发现,在使用 new 来调用函数时,会创建一个链接到函数原型的对象,并把它绑定到函数调用的 this,所以应用了 new 绑定规则后,不会被任何方式修改 this 指向:

【特殊】箭头函数中的this

ES6 中新增了一种函数类型,箭头函数[2],箭头函数中 this 不会应用上述规则,而是根据最外层的词法作用域来确定 this,简单来说,箭头函数的 this 就是它外面第一个不是箭头函数的函数的 this

关于this你可能还会看:《2w字大章 38道面试题》彻底理清JS中this指向问题

优先级

new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

判断模式

根据绑定规则和优先级,我们可以总结出 this 判断的通用模式,

  1. 函数是否通过 new 调用?
  2. 是否通过 call,apply,bind 调用?
  3. 函数的调用位置是否在某个上下文对象中?
  4. 是否是箭头函数?
  5. 函数调用是在严格模式还是非严格模式下?

总结

  • this 的绑定规则有四种:默认绑定,隐式绑定,显式绑定,new绑定
  • 无法应用其他 3 种规则时就是默认绑定,严格模式下 this 为 undefined,非严格模式下为全局对象
  • 函数在调用位置有上下文对象时,this 会隐式绑定到这个对象
  • 可以通过 call,apply,bind 显式地改变 this 的指向
  • 通过 new 调用时,this 会绑定到调用函数,new 绑定是优先级最高的绑定
  • 箭头函数中的 this 继承至它外层第一个不是箭头函数的函数

给TA买糖
共{{data.count}}人
人已赞赏
前端技术

我 JS 写的好好的,为什么要用那么复杂的TS

2021-12-22 21:05:16

前端技术

面试官对不起!我终于会了Promise...(一面凉经泪目)

2021-12-22 21:14:01

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索