4

我在 SO 上找到了一些有趣的例子。其中包括本文的链接。据说:

Function.__proto__指向Function.prototype. 这导致:

 Function.constructor === Function

也就是说:函数是它自己的构造函数!

Object instanceof Object == true.

这是因为:

Object.__proto__.__proto__.constructor == Object 

另请注意,与Object instanceof Object,不同Foo instanceof Foo == false。这是因为:Foo不作为它自己的原型链的构造函数存在。

从 Mozilla 开发者网络我发现原型和构造函数都可以很容易地被覆盖。而且由于instanceof只是检查constructor.prototype原型链,我真的不明白为什么我的代码仍然返回false

function Foo() { } ;
Foo.prototype = Foo
Foo.constructor = Foo
Foo instanceof Foo // still false

还有一些关于原型的问题。我做对了吗,原型本身是一个单独的辅助对象?这个对象就像另一个对象上的指针——通常Object

4

2 回答 2

4

obj instanceof不查找constructorin obj.prototype,而是在对象的内部__proto__属性中查找。

javascript 中的每个对象都有一个__proto__引用对象原型的内部属性。当使用new运算符构造对象时,该对象的内部__proto__属性设置为构造函数的prototype属性。

因此,当您说 时Foo instanceof Foo,javascript VM 将在Foo.__proto__. 因为 Foo 是一个函数,Foo.__proto__所以是Function.prototypeFunction函数的构造函数在哪里)。

由于您实际上无法更改对象的内部__proto__属性,因此 Foo 永远不能是 Foo 的实例。


关于你的小问题:在 javascript 中,一切都是对象。这包括原型函数。事实上,ECMAScript 5 添加了一个函数Object.create( MDN ),它以一个对象作为其第一个参数,然后使用第一个对象作为其内部原型对象创建一个新对象。

于 2013-04-14T00:06:05.107 回答
1

重要的是要记住,作为原型链一部分的对象的实际内部原型引用与对象的原型属性不同。对象的内部原型设置为其构造函数的原型属性

我在学习这个时发现最容易理解的文章实际上是这篇文章。

换句话说,改变prototype对象属性的唯一要点是该对象是否是一个应该用作构造函数的函数。除此之外,它没有什么神奇之处,它只是一个属性。改变prototype不会改变__proto__,也不会影响对象的原型链。

所以,通过代码:

function Foo() {}

Foo 的构造函数此时实际上是 Function,而 Function.prototype 是 Foo 的实际内部原型,或者__proto__如果你愿意的话。

Foo.prototype = Foo;

这只会改变 Foo 的原型属性,但不会改变它的内部原型。

Foo.constructor = Foo

这实际上只在 Foo 上设置了 constructor 属性,它对 Foo.prototype.constructor 没有任何作用,它也对 Foo 的内部原型的构造函数没有任何作用,这是instanceof检查的内容。


试试这个代码序列,希望它会更清楚一点:

function Foo() { } ;

(Foo.prototype != Function.prototype && Foo.__proto__ == Function.prototype);

Foo.prototype = Foo;

(Foo.prototype == Foo && Foo.__proto__ != Foo && Foo.__proto__ == Function.prototype);

Foo.constructor = Foo;

(Foo.constructor == Foo && Foo.prototype.constructor == Foo && Foo.__proto__.constructor != Foo);
于 2013-04-14T00:32:53.097 回答