理解JavaScript中的this
本文基本是对
的翻译整理。好像B站不让加入站外链接,想看原文自己搜去吧。另外吐槽一下原文写得其实很乱,只能尽量整理了。
不过其实this也不是什么难点,本文只是记录一下,万一哪天有知识点忘了可以尽快复习。
B站你什么时候才能支持markdown啊
在js使用者中,常有人抱怨this
的语义令人困惑。理解核心函数调用原语,并将所有其他调用函数的方式视为该原语之上的语法糖,可以消除这种困惑(ES规范就是这样理解的)。
本文去掉了一些原文中关于ES5的额外表述,基于ES6规范进行整理。

核心原语
首先关注核心函数调用原语,一个Function的call
方法,call方法相对来说很直接:
从第一个参数开始到最后一个参数结束,构建一个参数列表
argList
第一个参数是
thisValue
以
thisValue
作为this
,argList
作为参数列表调用该函数(如果熟悉python的话,可以尝试结合python的decorator去理解)
例:
如上面代码所描述,通过将this
设置为Yehuda
,以及一个单独的参数thing
,来调用hello
方法。这就是js的函数调用原语。
简单的函数调用
显然上述用call
调用函数的方式并不算实用,js允许以hello("world")
的方式进行函数调用,当我们这样做的时候,相当于:
概括地说,一个通过fn(...args)
方式调用的函数,与fn.call(window [ES5-strict: undefined], ...args)
是等价的。
看懂这句话后面不用看了,这文章核心内容就这一句,后面是bind、apply这些东西,不如翻MDN去

成员函数调用
函数经常被作为一个object的成员进行调用,在这种情况下:
上例中,hello
是如何绑定到一个object上是无关紧要的:

使用Function.prototype.bind
进行调用
以前人们经常通过闭包方式取巧地将函数的this值固定:
有了bind之后可以将上述内容改为更通用的写法:
为了理解上述写法,只需要明确以下两点:
arguments
是一个类似数组的object,表示所有传递给函数的参数apply
工作原理和call
原语一致,唯一区别在于apply
把所有参数打包在一起(arguments)接收,call
是一个个参数单独接收bind
方法返回一个新函数,当它被调用,新函数简单地调用传入的原始函数(person.hello
),将原始值设置为this
,其他参数照常传递。由于
bind
常被使用,ES5在Function
对象上实现了bind
,上例可以改为:

没了