通过更改构造函数属性动态替换原型

时间:2013-04-08 09:26:08

标签: javascript

我正在尝试制作一些优秀的代码示例来体验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会添加新属性,这会影响原始属性。为什么呢?..

3 个答案:

答案 0 :(得分:1)

是的,有Object.__proto__和直接Object.prototype。如果您打印One.prototype,您应该看到所需的结果。如果您执行console.dir(someInstance);,您将直接在someInstance下面列出实例变量。

之后,您可以展开prototype,您将看到为该原型定义的方法。(例如One.prototype.doSomething = function(a){});

详细了解Object.__proto__ HERE以及Object.prototype(标准)HERE的详情。

答案 1 :(得分:1)

最初,您的var obj没有名为constructor的媒体资源。当你打印它时,它通过它的原型(One.prototype)解决 - 所有原型都有一个构造函数。分配obj.constructor = Two时,在obj中创建一个自己的属性,该属性会隐藏prototype属性。这个新的prop对引擎没有任何意义,也不会以任何方式影响继承。

一般而言,“构造函数”似乎是纯粹的信息属性,并不用于任何特定目的。它只是从函数原型回到父函数的反向链接。有关详细信息,请参阅Creating functionsConstruct

答案 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