[英]JavaScript obj.constructor vs obj.[[Prototype]]'s constructor
Object.getPrototypeOf(z).constructor === z.constructor
Is this true for every object z
in JavaScript?这对于 JavaScript 中的每个 object
z
是否都是如此?
I mean is z.constructor
just a shortcut allowing us to retrieve more easily我的意思是
z.constructor
只是一个让我们更容易检索的快捷方式
the constructor property of the object's internal [[Prototype]]
property.对象内部
[[Prototype]]
属性的构造函数属性。
Or... are there cases in which the two differ and the z.constructor
value或者...是否存在两者不同以及
z.constructor
值的情况
is different from the Object.getPrototypeOf(z).constructor
value?不同于
Object.getPrototypeOf(z).constructor
值?
I think it is just shortcut but I am not sure as I don't find我认为这只是捷径,但我不确定,因为我找不到
this stated explicitly in any authoritative source of doc.这在任何权威的文档来源中都明确说明。
EDIT : This code below shows that setting Object.getPrototypeOf(z).constructor
implicitly sets the other value too.编辑:下面的代码显示设置
Object.getPrototypeOf(z).constructor
隐式设置其他值。 But setting z.constructor
does not set the other value.但是设置
z.constructor
不会设置其他值。
So now I am puzzled... how is this implemented?所以现在我很困惑......这是如何实现的? Seems
z.constructor
is not just a shortcut but some sort of copy.似乎
z.constructor
不仅是快捷方式,而且是某种副本。 But if it's a copy why is it affected when we change/set the Object.getPrototypeOf(z).constructor
to a new value?但是,如果它是副本,为什么当我们将
Object.getPrototypeOf(z).constructor
更改/设置为新值时它会受到影响?
function Animal() {
this.ttype = "Animal"
}
function Plant(){
this.ttype = "Plant"
}
var p1 = new Plant();
console.log(p1.constructor);
console.log(p1.constructor === Object.getPrototypeOf(p1).constructor);
p1.constructor = Animal;
console.log(p1.constructor === Object.getPrototypeOf(p1).constructor);
var p2 = new Plant();
console.log(p2.constructor);
console.log(p2.constructor === Object.getPrototypeOf(p2).constructor);
Object.getPrototypeOf(p2).constructor = Animal;
console.log(p2.constructor === Object.getPrototypeOf(p2).constructor);
console.log(p2.constructor);
The constructor
property of an object is normally inherited from it's prototype chain. object 的
constructor
属性通常继承自它的原型链。 There are two exceptions:有两个例外:
Objects whose prototype chain doesn't contain any objects.原型链不包含任何对象的对象。 These be created using
Object.create(null)
and are useful for setting up look up tables that aren't affected by properties inherited from somewhere else.这些是使用
Object.create(null)
创建的,对于设置不受从其他地方继承的属性影响的查找表很有用。
Objects that have been assigned a local "own" property called constructor
, as in已分配了名为
constructor
的本地“自己”属性的对象,如
myObject.constructor = 42;
However, this is a technicality and not something you would expect to see in real code.但是,这是技术性问题,而不是您希望在实际代码中看到的内容。
So leaving these aside, where is constructor
inherited from?那么抛开这些,
constructor
是从哪里继承的呢?
By language design, constructor
is inherited from the constructor function's prototype
property.通过语言设计,
constructor
函数继承自构造函数的prototype
属性。 Every plain vanilla function in JavaScript is set up with a prototype
property with a non enumerable property called constructor
set to the function object itself. Every plain vanilla function in JavaScript is set up with a
prototype
property with a non enumerable property called constructor
set to the function object itself. By this means any standard function can be called as a constructor without modification.通过这种方式,任何标准的 function 都可以作为构造函数调用而无需修改。 However the overhead is that standard functions never intended to be used as constructors have a
prototype
property anyway.然而,开销是标准函数从不打算用作构造函数,无论如何都具有
prototype
属性。
Now more complications:现在更复杂:
The prototype
property of a standard function object is writable.标准 function object 的
prototype
属性是可写的。 If it is updated to a new object value, objects constructed by the function will inherit constructor
from the ammended prototype
object - which would generally be different to the constructor
value of the overwritten prototype
value.如果将其更新为新的 object 值,则由 function 构造的对象将从修改后的
prototype
object 继承constructor
函数 - 这通常与被覆盖的prototype
的constructor
值不同。
The constructor
property of the prototype
property of a function is not write protected. function 的
prototype
属性的constructor
属性没有写保护。
In combination, these two factors allow setting up prototype chains of arbitrary length, simulating in part the extension of classes in a class based language.结合起来,这两个因素允许建立任意长度的原型链,部分模拟基于 class 的语言中的类扩展。 EG If
C
objects inherit from B
which inherit from A
you could write EG 如果
C
对象继承自B
继承自A
你可以写
B.prototype = new A() // B objects inherit from an instance of A, // which inherits from A.prototype C.prototype = new B() // C objects inherit from an instance of B, // which inherits from B.prototype and A.prototype C.prototype.constructor = C; // C objects inherit C as their constructor.
These classic rules for chaining prototypes are quite lax: you can change the prototype
property multiple times without affecting the inheritance chain of previously created objects.这些用于链接原型的经典规则非常宽松:您可以多次更改
prototype
属性而不会影响先前创建的对象的 inheritance 链。 However changing the prototype
property of a constructor function multiple times has limited use (creating a polyfill for Object.create
perhaps) and most unusual.但是,多次更改构造函数 function 的
prototype
属性的用途有限(可能为Object.create
创建 polyfill)并且最不寻常。
Note the class
keyword syntax to create constructor functions renders this kind of manipulation obsolete - you can't change a class constructor functions prototype
property, and if you extend a "class" the prototype
property of the extended class inherits from the base class's prototype
property while having its constructor
property set to the extended constructor, both automatically.请注意用于创建构造函数的
class
关键字语法使这种操作变得过时 - 您不能更改 class 构造函数prototype
属性,如果您扩展“类”,则扩展 ZA2F2ED4F8EBC2CBB4C21A29DC40 的prototype
属性继承自prototype
属性 AB同时将其constructor
属性设置为扩展构造函数,两者都是自动的。
Also note that arrow functions don't have a prototype
property and cannot be used as constructors.另请注意,箭头函数没有
prototype
属性,不能用作构造函数。
q1 q1
Object.getPrototypeOf(z).constructor === z.constructor
Is this true for every object z in JavaScript?这对于 JavaScript 中的每个 object z 是否都是如此?
Yes, except for the exceptions listed under 1) and 2).可以,但 1) 和 2) 中列出的例外情况除外。
q2 q2
p1.constructor = Animal;
This creates an own property of p1
that shadows the inherited constructor
property which can no longer be accessed (exception 2)这会创建一个自己的
p1
属性,它会隐藏无法再访问的继承的constructor
属性(异常 2)
q3 q3
Object.getPrototypeOf(p2).constructor = Animal;
This line of code updates the constructor
property of the object from where p2
inherits its constructor
value from, so p2
's inherited constructor property is now Animal
.这行代码更新了 object 的
constructor
属性, p2
从其中继承了它的constructor
值,因此p2
的继承构造函数属性现在是Animal
。 Other plant objects which similarly inherit from Plant.prototype
would also see Animal
as their constructor.类似地从
Plant.prototype
继承的其他植物对象也会将Animal
视为它们的构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.