文章介绍
大家在平常的项目开发、JavaScript学习过程中一定都遇到this它指向谁这个问题吧,有时你觉得它应该指向window,结果它告诉你ReferenceError指向了undefined。带着这样的疑问,我们一起来探究一下this指向的奥秘。
一、this到底是什么
如果大家学习过Java这一类面向对象开发的语言时,会在创建对象时使用到this,下意识的认为javascript中的this也是类似Java会指向函数本身。但这种情况实际上只作用于构造函数(使用new关键字调用的JS函数),在其他的情况下this的指向受到函数所处条件影响。
this其实是一种执行时上下文,只有在函数执行时才可以确定并使用this关键字。那么肯定有同学会问了,什么是执行时呢?指的是函数this的指向不会受到所处的词法作用域影响,而是受函数执行时所处环境条件决定。
举个例子吧:

二、this指向的四条规则
这里推荐大家阅读《你不知道的JavaScript》,其中对this有比较清晰的剖析,重点是例子比较多便于理解。
1. 默认绑定(独立调用)
在书上对于本条规则的命名为默认绑定,而我个人认为独立调用更便于理解。独立调用顾名思义,便是函数独自执行,并不是作为对象方法执行、不是作为构造函数执行没有被显示的修改this指向的执行方式。在这种情况下,this指向默认指向当前环境(浏览器环境、node环境等)的全局对象,比如在浏览器环境中函数的this默认指向window对象,且不受所处执行位置的影响。

通过上述例子,想必大家也可以大概了解什么是独立调用。也就是不论函数被定义在哪个词法作用域中,只要调用函数时是直接通过函数名+()表达式的方式调用,那么这个函数的执行就属于独立调用,此时函数的this便指向的是函数所处环境的全局对象。这里要补充一点,如果这个函数处于严格模式下,比如使用type=module的js类型、使用use strict关键字的条件下,独立调用的this默认指向的是undefined。
2. 显示绑定
这个我猜想是大家使用的非常多的一种改变函数this指向的方法,在模块化开发时我们经常会给页面元素绑定事件处理函数,而众所周知事件处理函数的this指向默认指向绑定的元素,因此我们需要通过显示绑定的方式将this绑定函数所处的模块对象。

通过以上的函数我们可以达到以下效果:

当然使用apply、bind也是可以修改函数this的指向的,用法与call一致。可能会有同学不了解这三者之间的区别,我们展开了解一下:
| 方法 | 第一个参数 | 第二个参数 | 立即执行 |
|---|---|---|---|
| call | this指向 | 携带的散列参数 | 立即执行 |
| apply | this指向 | 携带的参数数组 | 立即执行 |
| bind | this指向 | 携带的散列参数 | 非立即执行,返回新函数 |
从上述表格中我们可以根据接收的参数形式将call、bind分为一组、apply为一组,也可以根据是否立即执行进行分组,我们分别使用一个例子来展示吧。

除此之外,在使用call、apply、bind方法时,如果不想修改this指向而单纯的想添加默认的参数值时,可以向第一个参数中填写undefined或null,则this指向不会发生修改。比如说一个函数接收多个形参,而我们从后端得到的数据是一个数组的形式,通过arr[0]、arr[1]...的形式填写参数比较繁琐且操作性不强,此时我们可以使用到apply函数,以数组的参数传入参数。

3. 隐式绑定(对象调用)
这种this指向的方式应该是比较常见的,同样的笔者认为对象调用会比隐式绑定更容易理解。也就是函数作为对象的方法调用时,此时的this将指向调用此函数的对象本身。

4. new
如果知道new关键实质的同学应该非常容易理解。new fn()干了什么呢?实质上如果不需要传入参数,()表达式都可以省略。new关键字实际上隐式的创建了一个this对象,将构造函数中对应的this属性赋值之后又隐式的将this对象返回给外界的接收对象。

三、规则优先级
知道了this指向的四条规则,那么他们之间的优先级顺序又是什么呢?这里直接给出结果,大家可以自己编写demo代码进行测试。new关键字>显示绑定>隐式绑定>默认绑定。
四、总结
从本文中大家可以简单了解到this的概念,以及this指向的四条规则及其优先级。本文提供的案例还是相对较少,因为并没有在本文中特别的深入this的各种情况,想必学过ES6箭头函数的同学会了解到箭头函数this的特殊性。大家如果想深入的了解this的指向,笔记建议可以先了解其四种规则再进行针对性刷题。
我是Donp1,我们下次见~🐻❄️
本文介绍了JavaScript中this关键字的概念及四种指向规则:默认绑定、显示绑定、隐式绑定与new调用,并探讨了它们之间的优先级。
1311

被折叠的 条评论
为什么被折叠?



