Skip to content

关于箭头函数this的理解几乎完全是错误的 #150

Closed
@darkrainChn

Description

@darkrainChn

我原来的观点有误,修改掉吧。

我在发此文之前,曾经考虑过到底是我对原文理解有偏差,还是原文有误。最后判断是原文有误,现在看来是我错误判断了。
前面我也写到过以下文字——

这里说的lambda表达式的“定义时”,指的是代码运行过程中“遇到”lambda表达式的时候,它和代码的上下文没有关系,而是和运行时的上下文有关。
我们可以把lambda表达式看成一个变量,在代码运行“遇到”(看见)它之前,这个变量是未定义的;遇到的时候,就会把运行时的上下文绑定在展开函数的this上。此时lambda表达式内部的操作并没有被执行,它作为一个已经被定义并绑定了this的函数实体存在,等待被实际调用。

这里强调我也强调了函数定义是一个动态的概念,是外层代码执行时才产生了箭头函数的定义。之所以会觉得原文有问题,是因为“定义”这个词配合上“外层”的概念,很容易让人理解为:原文提到的“定义”是一个代码层面的概念,并且是与代码书写位置有关的,而不是一个“运行时”的概念。所以我会认为原文是错的。
现在再看这个问题,其实在这方面我们的观点是一致的,即箭头函数的this是它真正被定义时候的“运行时”上下文,而不是箭头函数实际使用(即内部语句被执行)时的上下文。结果对于原文理解不同,造成对原文错误的判断评价。

上面说的是一个理解问题,但接下来说的就是我本身的错误了。
对于“所有的箭头函数都没有自己的this,都指向外层”这句话,经过其他人的解释,我已经知道这是正确的表述了。而我对于箭头函数的展开:
var f = () => 5;
var f = function(){return 5;}.bind(this);
并不符合真正的实现机制。我这种展开方式,只是看上去效果与箭头函数差不多,除了这种展开后的函数可以被用作对象构造函数这一点差异外,不能再手动指定this、不能重新绑定其他的this,这个特性则是相同的。这种展开只能说是一种近似方式,它并不等价于原箭头函数,只是可能可以作为将代码改写为低版本时的一种实现方式。

我前面还提到扩展运算符所谓的“逆运算”问题,现在看来也只是理解方式不同造成的困惑,并不能说原书有错。
至于提到的另外2个小问题,目前看来确实是问题,但也只是小问题而已。回头找个时间再把它们写出来。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions