[英]Using `super()` when extending `Object`
I'm creating a class that extends Object
in JavaScript and expect super()
to initialise the keys/values when constructing a new instance of this class. 我正在创建一个在JavaScript中扩展
Object
的类,并期望super()
在构造此类的新实例时初始化键/值。
class ExtObject extends Object { constructor(...args) { super(...args); } } const obj = new Object({foo:'bar'}); console.log(obj); // { foo: 'bar' } const ext = new ExtObject({foo:'bar'}); console.log(ext); // ExtObject {} console.log(ext.foo); // undefined
Why isn't foo
defined as 'bar'
on ext
in this example? 为什么不是
foo
定义为'bar'
上ext
在这个例子吗?
EDIT 编辑
Explanation : Using `super()` when extending `Object` 说明 : 扩展`Object`时使用`super()`
Solution : Using `super()` when extending `Object` 解决方案 : 扩展`Object`时使用`super()`
Nobody has actually explained why it doesn't work. 实际上没有人解释为什么它不起作用。 If we look at the latest spec , the
Object
function is defined as follows: 如果我们查看最新的规范 ,
Object
函数定义如下:
19.1.1.1 Object ( [ value ] )
19.1.1.1对象([value])
When
Object
function is called with optional argumentvalue
, the following steps are taken:使用可选参数
value
调用Object
函数时,将执行以下步骤:
- If
NewTarget
is neitherundefined
nor the active function, then如果
NewTarget
既不是undefined
也不是活动函数,那么
- Return ?
回来?
OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%")
.OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%")
。- If
value
isnull
,undefined
or not supplied, returnObjectCreate(%ObjectPrototype%)
.如果
value
为null
,undefined
或notObjectCreate(%ObjectPrototype%)
,则返回ObjectCreate(%ObjectPrototype%)
。- Return !
回来了!
ToObject(value)
.ToObject(value)
。
The first step is the important one here: NewTarget
refers to the function that new
was called upon. 第一步是重要的一步:
NewTarget
指的是调用new
的函数。 So if you do new Object
, it will be Object
. 因此,如果您执行
new Object
,它将是Object
。 If you call new ExtObject
it will ExtObject
. 如果你调用
new ExtObject
,它将是ExtObject
。
Because ExtObject
is not Object
( "nor the active function" ), the condition matches and OrdinaryCreateFromConstructor
is evaluated and its result returned. 因为
ExtObject
不是Object
( “也不是活动函数” ),所以条件匹配并且会计算OrdinaryCreateFromConstructor
并返回其结果。 As you can see, nothing is done with the value
passed to the function. 如您所见,传递给函数的
value
没有任何作用。
value
is only used if neither 1. nor 2. are fulfilled. 只有在不满足1和2的情况下才使用该
value
。 And if value
is an object, it is simply returned as is, no new object is created. 如果
value
是一个对象,它只是按原样返回,不会创建新对象。 So, new Object(objectValue)
is actually the same as Object(objectValue)
: 因此,
new Object(objectValue)
实际上与Object(objectValue)
相同:
var foo = {bar: 42}; console.log(new Object(foo) === foo); console.log(Object(foo) === foo);
In other words: Object
does not copy the properties of the passed in object, it simply returns the object as is. 换句话说:
Object
不会复制传入的对象的属性,它只是按原样返回对象。 So extending Object
wouldn't copy the properties either. 因此,扩展
Object
也不会复制属性。
You are missing the Object.assign 您缺少Object.assign
class ExtObject extends Object { constructor(...args) { super(...args); Object.assign(this, ...args); } } const obj = new Object({foo:'bar'}); console.log(obj); // { foo: 'bar' } const ext = new ExtObject({foo:'bar'}); console.log(ext); // { foo: 'bar' } console.log(ext.foo); // bar
This answer works only when using the Babel transpiler. 这个答案只有在使用Babel转换器时才有效。
Because Object's constructor returns value. 因为Object的构造函数返回值。 See spec
见规格
15.2.2.1 new Object ( [ value ] )
15.2.2.1新对象([value])
When the Object constructor is called with no arguments or with one argument value, the following steps are taken:如果在没有参数或具有一个参数值的情况下调用Object构造函数,则执行以下步骤:
......
8. Returns obj.8. 返回obj。
class ExtObject extends Object { constructor(...args) { return super(...args); } } const obj = new Object({foo:'bar'}); console.log(obj); // { foo: 'bar' } const ext = new ExtObject({foo:'bar'}); console.log(ext); // { foo: 'bar' } console.log(ext.foo); // bar
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.