ES6 使用静态方法创建新实例为 child class 属性提供未定义
ES6 using static method to create new instance gives undefined for child class attributes
我有以下 child class:
export default class File extends Model {
selected = false
}
和 parent class:
export default class Model {
constructor (attributes = {}) {
if (new.target === Model) {
throw Error('Not allowed to instantiate Model')
}
Object.assign(this, attributes)
}
static build (attributes) {
return new this(attributes)
}
}
我预计在使用
时
const file = File.build({selected: true})
file.selected 的结果本来是正确的,但仍然是错误的。在构造函数中记录 "this",我可以看到 File 实例根本没有 selected 属性,返回未定义。
使用当前的 babel 配置
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current'
}
},
'@babel/preset-typescript'
]
],
plugins: [
'@babel/plugin-transform-typescript',
'@babel/plugin-proposal-class-properties'
]
}
如果我没有在 child class 上定义 selected,则 file.selected
的结果将为真
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_fields:
Public instance fields are added with Object.defineProperty
either at construction time in the base class (before the constructor body runs), or just after super()
returns in a subclass.
this.selected
没有及时设置以便父构造函数看到它(当允许在构造函数中使用 this
时匹配)。一种替代方法是将初始值放在原型上:
File.prototype.selected = false;
你能把 Object.assign
移到 build
方法而不是构造函数吗?
示例:
class Model {
constructor () {
if (new.target === Model) {
throw Error('Not allowed to instantiate Model')
}
}
static build (attributes) {
const obj = new this(attributes)
Object.assign(obj, attributes)
return obj
}
}
class File extends Model {
constructor() {
super()
this.selected = false
this.defaultValue = 'default'
}
}
const file = File.build({selected: true, foo: 'bar'})
console.log(file);
我有以下 child class:
export default class File extends Model {
selected = false
}
和 parent class:
export default class Model {
constructor (attributes = {}) {
if (new.target === Model) {
throw Error('Not allowed to instantiate Model')
}
Object.assign(this, attributes)
}
static build (attributes) {
return new this(attributes)
}
}
我预计在使用
时const file = File.build({selected: true})
file.selected 的结果本来是正确的,但仍然是错误的。在构造函数中记录 "this",我可以看到 File 实例根本没有 selected 属性,返回未定义。
使用当前的 babel 配置
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current'
}
},
'@babel/preset-typescript'
]
],
plugins: [
'@babel/plugin-transform-typescript',
'@babel/plugin-proposal-class-properties'
]
}
如果我没有在 child class 上定义 selected,则 file.selected
的结果将为真https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_fields:
Public instance fields are added with
Object.defineProperty
either at construction time in the base class (before the constructor body runs), or just aftersuper()
returns in a subclass.
this.selected
没有及时设置以便父构造函数看到它(当允许在构造函数中使用 this
时匹配)。一种替代方法是将初始值放在原型上:
File.prototype.selected = false;
你能把 Object.assign
移到 build
方法而不是构造函数吗?
示例:
class Model {
constructor () {
if (new.target === Model) {
throw Error('Not allowed to instantiate Model')
}
}
static build (attributes) {
const obj = new this(attributes)
Object.assign(obj, attributes)
return obj
}
}
class File extends Model {
constructor() {
super()
this.selected = false
this.defaultValue = 'default'
}
}
const file = File.build({selected: true, foo: 'bar'})
console.log(file);