我正在尝试制作一些优秀的代码示例来体验JavaScript的“无类别”。这是我到目前为止所提出的:
function One() {}
function Two() {}
One.prototype.a = 5;
Two.prototype.b = 4;
var obj = new One();
print("1) ctor =", obj.constructor, "a =", obj.a, " b =", obj.b);
obj.constructor = Two;
print("1) ctor =", obj.constructor, "a =", obj.a, " b =", obj.b);
var objTwo = new obj.constructor();
print("2) ctor =", objTwo.constructor, "a =", objTwo.a, " b =", objTwo.b);
这些是相应的印刷品:
1) ctor = function One() {
} a = 5 b = undefined
1) ctor = function Two() {
} a = 5 b = undefined
2) ctor = function Two() {
} a = undefined b = 4
我的问题是为什么原型链在这里不起作用?我使用JavaScript(spidermonkey)(spidermonkey-1.7)在ideone中运行我的示例。看起来在现实生活中原型是以constructor.prototype
以外的其他方式访问的?
P.S。进一步的实验表明,分配给obj.constructor
会添加新属性,这会影响原始属性。为什么呢?..
答案 0 :(得分:1)
是的,有Object.__proto__
和直接Object.prototype
。如果您打印One.prototype,您应该看到所需的结果。如果您执行console.dir(someInstance);
,您将直接在someInstance
下面列出实例变量。
之后,您可以展开prototype
,您将看到为该原型定义的方法。(例如One.prototype.doSomething = function(a){}
);
答案 1 :(得分:1)
最初,您的var obj
没有名为constructor
的媒体资源。当你打印它时,它通过它的原型(One.prototype
)解决 - 所有原型都有一个构造函数。分配obj.constructor = Two
时,在obj
中创建一个自己的属性,该属性会隐藏prototype属性。这个新的prop对引擎没有任何意义,也不会以任何方式影响继承。
一般而言,“构造函数”似乎是纯粹的信息属性,并不用于任何特定目的。它只是从函数原型回到父函数的反向链接。有关详细信息,请参阅Creating functions和Construct。
答案 2 :(得分:0)
这里的问题是你进入机械师然后开始拉线。书中没有任何内容真正发生在这里,因为你通过注入这个指针来破坏自然序列
obj.constructor = Two;
这不是继承的正确方法。这是:
function One() {}
function Two() {}
One.prototype.a = 5;
Two.prototype = new One();
Two.prototype.b = 4;
现在,使用new Two()
实例化的任何对象都将在构造函数中正确显示is-a
关系(继承)。这是一个显示差异的 jsFiddle Demo 。