gpt4 book ai didi

javascript - 真的被javascript es6箭头函数的 "enclosing scope"搞糊涂了

转载 作者:搜寻专家 更新时间:2023-11-01 04:29:28 24 4
gpt4 key购买 nike

  • 我在网上做了很多研究,阅读了很多帖子,包括 MDN 等等。
  • 我理解,对于传统定义的函数,函数中的“this”是由调用/调用它们的对象定义的(以及几种不同的情况,对象字面量、新构造函数、事件处理程序等)。
  • 我知道对于箭头函数,“this”是通过封闭的上下文/范围在词法上定义的,而不是通过调用它们的对象(尽管我们可以使用传统定义的函数(比如,A)包装箭头函数(比如 B),从而将对象引用先传递给 A,然后再传递给 B)

问题来了:

  1. 封闭上下文到底是什么?这更加复杂,因为 ES6 允许 {} 成为 block /范围/上下文。 {} 作为分隔符是否足以定义“封闭上下文”,或者它必须在函数范围内。

  2. 一个具体的例子:

     let EventEmitter = require('events').EventEmitter;
    class Person extends EventEmitter {
    constructor(name) {
    super();
    this.name = name;
    }
    }
    let mary = new Person('mary');
    mary.on('speak', (said) => {
    console.log(`${this.name}: ${said}`);
    });
    mary.emit('speak', 'you may delay, but time will not');

它只是设置一个自定义事件,并在触发自定义事件时添加一个回调函数。为什么这里的箭头功能不起作用?

“mary”是调用“on”函数的对象,应该将“on”中的“this”设置为“mary”。最重要的是,箭头函数是在其参数位置的“on”函数中定义的(从词法上来说足够了,对吧?),为什么箭头函数无法从其“封闭上下文”中获取“this”值,即,这里的“on”功能???

  1. 同样的例子,有常规的函数定义:

     let EventEmitter = require('events').EventEmitter;
    class Person extends EventEmitter {
    constructor(name) {
    super();
    this.name = name;
    }
    }
    let mary = new Person('mary');
    mary.on('speak', function(s) {
    console.log(this);
    });
    mary.emit('speak', 'you may delay, but time will not');

现在可以了。我知道,鉴于函数定义的旧方法,console.log(this) 现在可以动态绑定(bind)到调用它的对象。但是等等,“mary”是对象,“on”是被调用的直接函数。 “on”不应该为其中的匿名函数形成一个闭包吗?我记得嵌套函数中的“this”无法访问其闭包的“this”(又是封闭上下文,呵呵),因此不应该获得“mary”引用。为什么它在这里起作用?

  1. 当我们在函数中谈论某事(比如 A)时,是否意味着 A 必须在函数的 {} 中,或者 A 可以在参数/参数区也是?也就是说,function(){A}function(A){}

  2. 类似地,如果将箭头函数作为参数传递,如 function(()=>()) {},外部函数是否考虑其封闭范围?或者在这种情况下封闭范围将是外部函数的外部?

以上内容可能听起来很愚蠢。非常感谢您的帮助。

最佳答案

我在这里可能并没有准确地使用作用域这个词,但基本上只是将作用域视为变量名到它们所指的内存位置的映射;嵌套作用域的名称/变量对 shadow(覆盖)在封闭(也称为父)作用域中具有相同名称的关联。

function foo() { // this is the "enclosing scope" of bar
var a = 4 <-----------+
|
var b = a // refers to --+

function bar() {
var a = 7 <-----------+
|
var c = a // refers to --+
}
}

this 的行为方式与上述示例中的 a 完全相同。

function 作用域隐式定义了对 this 的引用,但 ES2015 箭头函数作用域和 block 作用域没有。如果这些定义是明确的,那么这些定义会是这样的:

function foo() { // this is the enclosing scope of baz and the block below
var this = ... <-----------+--+
| |
var b = this // refers to --+ |
|
{ |
var q = this // refers to ---+
}

function bar() { // this is the enclosing scope of baz
var this = ... <-----------+--+
| |
var c = this // refers to --+ |
|
var baz = () => { |
var d = this // refers to ---+
}
}
}

this 在特定范围内引用的内存位置的实际 不是词法定义的;它在运行时设置为调用函数的对象(的内存位置)。但是一个引用对另一个引用的遮蔽总是在词法上定义的。

关于javascript - 真的被javascript es6箭头函数的 "enclosing scope"搞糊涂了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42847683/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com