【问题标题】:Does the ES7 decorator spec require descriptors to have an `initializer` methodES7 装饰器规范是否要求描述符具有 `initializer` 方法
【发布时间】:2015-10-04 16:25:21
【问题描述】:

使用 Babel 转译以下 es7 代码:

let obj = {
  @decorate
  prop: 10
}

let decorate = ( object, propertyName, desc ) => desc

当调用decorate 时,属性描述符desc 包含一个名为initializer 的方法,该方法在执行时返回obj.prop 的值。

initializer 方法是 es7 装饰器规范的一部分,还是这纯粹是 Babel 转换为 es5 的副作用?

【问题讨论】:

    标签: javascript decorator ecmascript-harmony ecmascript-2016


    【解决方案1】:

    es7 装饰器规范

    请注意,既没有 ES7,也没有装饰器的规范。有一个草稿,一个和谐提案,关于如何扩展语言。

    decorate被调用时,属性描述符desc包含一个名为initializer的方法

    这有点奇怪。从current proposal 开始,我预计总是使用该属性的属性描述符调用装饰器,这将是

    {value: 10, writable: true, enumerable: true, configurable: true}
    

    为你的例子。但是,草案中的示例仅概述了类和对象字面量上的方法(和访问器属性)的装饰器,而不是值属性。

    初始化方法是装饰器提案的一部分吗?

    目前没有,但他们的存储库中有一个INITIALIZER_INTEROP.md 文件,其中概述了装饰器与class properties proposal 中的PropertyInitialisers 的互操作性(这是一个未完成的草案,但也已经在 babel 中实现)。它确实使用了静态装饰器,这些装饰器被赋予带有 initializer 函数的描述符,该函数将被评估以在构造函数中(之前)初始化实例属性。

    这纯粹是 Babel 转换为 es5 的副作用吗?

    不是真的。 IMO it's just a bug,可能源于 babel 如何转译类属性,这使得它们看起来与对象字面量上的值属性相同。

    【讨论】:

    • 谢谢,正如我所料。可以安全地假设您不能依赖 initializer 作为返回值的方法
    • 我认为假设 initializer 总是返回值是省事的,但实际上你确实不能依赖 babel 的实验功能中的任何东西。
    【解决方案2】:

    如果您考虑proposal-class-fields TC39 提案,initializer 函数最有意义。

    考虑以下代码:

    class C {
      prop = {};
    }
    
    const a = new C()
    const b = new C()
    
    console.log(a.prop === b.prop)
    

    您会期望输出为false

    因此,属性的“值”不能存储为静态value,而是必须编码为每次都返回新值(此处为空对象)的函数。

    该代码被转换为相当于:

    class C {
        constructor () {
            const propName = 'prop'
            const propDesc = Object.getOwnPropertyDescriptor(this.constructor.prototype, propName)
            this[propName] = propDesc.initializer.call(this)
        }
    }
    

    这还允许您在声明其他实例变量时引用this(仍在该提案的上下文中):

    class C {
        entries = [ 1, 2, 3 ];
        count = this.entries.length;
    }
    

    由于class C 基本上是编写C.prototype 的语法糖,所以类属性上的装饰器实际上与对象属性上的装饰器相同(在这种情况下,对象是原型)。

    initializer 模式允许在这两种情况下使用单一方式编写装饰器。

    【讨论】:

      猜你喜欢
      • 2019-08-01
      • 1970-01-01
      • 2020-09-06
      • 2013-03-12
      • 2016-04-21
      • 2020-07-24
      • 2016-02-11
      • 2016-02-11
      • 1970-01-01
      相关资源
      最近更新 更多