被JavaScript的构造函数和原型搞糊涂了吗?

6
function MyObject(){}
Array.prototype={};
MyObject.prototype={};
var a=new Array();
var b=new MyObject();
alert(a.constructor==Array);//true
alert(b.constructor==MyObject);//false

这里有一篇很好的文章:http://joost.zeekat.nl/constructors-considered-mildly-confusing.html - nicosantangelo
谢谢,我正在阅读它。 - simon xu
确实,这些东西非常令人困惑!请查看我关于此主题的文章;也许它会帮助你理清思路。http://blogs.msdn.com/b/ericlippert/archive/2003/11/06/53352.aspx - Eric Lippert
3个回答

9

Array.prototype是一个不可写的属性。

因此,你的赋值操作:

Array.prototype = {}

...由于它没有成功,因此其 .constructor 属性未更改。

15.4.3.1 Array.prototype

Array.prototype 的初始值是 Array 原型对象 (15.4.4)。

此属性具有以下特性:{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }

...而对于您的自定义构造函数,您可以分配不同的原型对象,因此您已经覆盖了原始对象,该对象通过 .constructor 引用构造函数。


2

当你用自己的空对象实例覆盖prototype属性时,constructor属性会被重写,因为({}).constructor === Object。你可以选择以下任一方式:

function MyObject() {}
MyObject.prototype = {};
MyObject.prototype.constructor = MyObject;

或者(在我看来更好的方法)你可以不直接设置prototype,而是进行扩展:

function MyObject() {}
MyObject.prototype.foo = "bar";

此外需要注意的是: Array.prototype 不可写,因此你的代码 Array.prototype = {} 无声无息地失败(或在严格模式下会有提示)。

0
> function MyObject(){} 
> Array.prototype={};

你不能给Array.prototype赋值。

> MyObject.prototype={};
> var a=new Array();
> var b=new MyObject();
> alert(a.constructor==Array);//true

Array.prototype 拥有一个 constructor 属性,用于引用 Array 函数。由于 a 是 Array 的一个实例,它继承了 Array.prototype 的 constructor 属性。

> alert(b.constructor==MyObject);//false

你已经将一个空对象分配给了MyObject.prototype,它没有prototype属性,也没有b

MyObject.prototype.constructor = MyObject;

alert(b.constructor==MyObject); // true

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接