ES7 装饰器规范是否要求描述符具有 `initializer` 方法
Does the ES7 decorator spec require descriptors to have an `initializer` method
使用 Babel 转译以下 es7 代码:
let obj = {
@decorate
prop: 10
}
let decorate = ( object, propertyName, desc ) => desc
当 decorate
被调用时,属性 描述符 desc
包含一个名为 initializer
的方法,即 returns obj.prop
的值执行时。
initializer
方法是 es7 装饰器规范的一部分,还是这纯粹是 Babel 转换为 es5 的副作用?
es7 Decorator specification
请注意,目前还没有 ES7,也没有装饰器规范。有一个草案,一个关于如何扩展语言的和谐提案。
When decorate
is called, the property descriptor desc
contains a method named initializer
这有点奇怪。从 current proposal 我期望装饰器总是用 属性 描述符调用 属性,这将是
{value: 10, writable: true, enumerable: true, configurable: true}
以你为例。但是,草案中的示例只概述了方法(和访问器属性)的装饰器,包括 classes 和对象文字,而不是值属性。
Is the initializer method part of the Decorator proposal?
目前没有,但有一个 INITIALIZER_INTEROP.md file in their repository which outlines interoperability of decorators with the PropertyInitialisers
from the class properties proposal(这是一个未完成的草案,但也已经在 babel 中实现)。它确实使用了静态装饰器,这些装饰器被赋予了带有 initializer
函数的描述符,该函数将被评估以在构造函数(之前)中初始化实例 属性。
is this purely a side effect of Babel converting to es5?
不是真的。 IMO it's just a bug,可能源于 babel 如何转译 class 属性,这使得它们看起来与对象文字上的值属性相同。
如果您考虑 proposal-class-fields TC39 提案,initializer
函数最有意义。
考虑以下代码:
class C {
prop = {};
}
const a = new C()
const b = new C()
console.log(a.prop === b.prop)
您希望输出为 false
。
因此,属性 的 "value" 不能存储为静态 value
,而必须编码为 returns 新函数每次的值(这里是一个空对象)。
该代码被转译为等同于:
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
的语法糖,class 属性上的装饰器实际上与对象属性上的装饰器相同(在这种情况下,对象是原型).
initializer
模式允许在这两种情况下使用单一方式编写装饰器。
使用 Babel 转译以下 es7 代码:
let obj = {
@decorate
prop: 10
}
let decorate = ( object, propertyName, desc ) => desc
当 decorate
被调用时,属性 描述符 desc
包含一个名为 initializer
的方法,即 returns obj.prop
的值执行时。
initializer
方法是 es7 装饰器规范的一部分,还是这纯粹是 Babel 转换为 es5 的副作用?
es7 Decorator specification
请注意,目前还没有 ES7,也没有装饰器规范。有一个草案,一个关于如何扩展语言的和谐提案。
When
decorate
is called, the property descriptordesc
contains a method namedinitializer
这有点奇怪。从 current proposal 我期望装饰器总是用 属性 描述符调用 属性,这将是
{value: 10, writable: true, enumerable: true, configurable: true}
以你为例。但是,草案中的示例只概述了方法(和访问器属性)的装饰器,包括 classes 和对象文字,而不是值属性。
Is the initializer method part of the Decorator proposal?
目前没有,但有一个 INITIALIZER_INTEROP.md file in their repository which outlines interoperability of decorators with the PropertyInitialisers
from the class properties proposal(这是一个未完成的草案,但也已经在 babel 中实现)。它确实使用了静态装饰器,这些装饰器被赋予了带有 initializer
函数的描述符,该函数将被评估以在构造函数(之前)中初始化实例 属性。
is this purely a side effect of Babel converting to es5?
不是真的。 IMO it's just a bug,可能源于 babel 如何转译 class 属性,这使得它们看起来与对象文字上的值属性相同。
如果您考虑 proposal-class-fields TC39 提案,initializer
函数最有意义。
考虑以下代码:
class C {
prop = {};
}
const a = new C()
const b = new C()
console.log(a.prop === b.prop)
您希望输出为 false
。
因此,属性 的 "value" 不能存储为静态 value
,而必须编码为 returns 新函数每次的值(这里是一个空对象)。
该代码被转译为等同于:
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
的语法糖,class 属性上的装饰器实际上与对象属性上的装饰器相同(在这种情况下,对象是原型).
initializer
模式允许在这两种情况下使用单一方式编写装饰器。