Object.getPrototypeOf(z).constructor === z.constructor
JavaScript中的每个对象z
都是这样吗?
我的意思是z.constructor
只是一个捷径,使我们可以更轻松地检索
对象内部[[Prototype]]
属性的构造方法属性。
或者...在某些情况下,两者和z.constructor
值不同
与Object.getPrototypeOf(z).constructor
值不同吗?
我认为这只是捷径,但我不确定,因为我找不到
在任何权威文档中都明确指出了这一点。
编辑:
下面的代码显示设置Object.getPrototypeOf(z).constructor
也隐式设置了另一个值。但是设置z.constructor
不会设置其他值。
所以现在我感到困惑...如何实现?看来z.constructor
不仅是捷径,而且还是某种复制品。但是,如果是副本,为什么在我们将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);
答案 0 :(得分:1)
对象的constructor
属性通常是从其原型链继承的。有两个例外:
其原型链不包含任何对象的对象。它们是使用Object.create(null)
创建的,对于设置不受其他地方继承的属性影响的查找表很有用。
已被分配为constructor
的本地“拥有”属性的对象,如
myObject.constructor = 42;
但是,这只是技术问题,而不是您希望在实际代码中看到的东西。
那么撇开这些,constructor
是从哪里继承的?
通过语言设计,constructor
继承自构造函数的prototype
属性。 JavaScript中的每个普通香草函数都设置有一个prototype
属性,并且将一个不可枚举的属性constructor
设置为函数对象本身。通过这种方法,任何标准函数都可以作为构造函数调用而无需修改。但是,开销是,从不打算用作构造函数的标准函数始终具有prototype
属性。
现在更多的并发症了:
标准函数对象的prototype
属性是可写的。如果将其更新为新的对象值,则由该函数构造的对象将从继承的constructor
对象继承prototype
-通常与改写后的{{ 1}}值。
函数的constructor
属性的prototype
属性不受写保护。
结合起来,这两个因素允许建立任意长度的原型链,部分模拟基于类语言的类扩展。如果constructor
个对象继承自prototype
的{{1}}个对象,您可以编写
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.
创建一个polyfill),并且最不常见。
请注意,用于创建构造函数的prototype
关键字语法使这种操作变得过时了-您不能更改类构造函数的prototype
属性,如果扩展了“类”,则{{扩展类的1}}属性继承自基类的Object.create
属性,而其class
属性则自动设置为扩展构造函数。
还请注意,箭头函数没有prototype
属性,因此不能用作构造函数。
q1
prototype
JavaScript中的每个对象z都适用吗?
是,除了1)和2)中列出的例外。
q2
prototype
这将创建自己的属性constructor
,该属性遮盖了无法再访问的继承的prototype
属性(异常2)
q3
Object.getPrototypeOf(z).constructor === z.constructor
此行代码更新了对象p1.constructor = Animal;
从p1
继承其constructor
值的对象的属性,因此Object.getPrototypeOf(p2).constructor = Animal;
的继承构造函数属性现在为{{ 1}}。同样从constructor
继承的其他植物对象也将p2
视为其构造函数。