Javascript函数覆盖原型

时间:2013-04-13 22:21:22

标签: javascript oop function object prototype

我在SO上发现了一些有趣的例子。其中包括与此article的链接。  它说:

  

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

 Function.constructor === Function
  

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

Object instanceof Object == true.

这是因为:

Object.__proto__.__proto__.constructor == Object 
  

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

从Mozilla开发人员网络中我发现原型和构造函数都可以轻松覆盖。由于instanceof只检查原型链中的constructor.prototype,因此我无法理解为什么我的代码仍会返回false

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

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

2 个答案:

答案 0 :(得分:4)

obj instanceof不会在constructor中查找obj.prototype,而是在对象的内部__proto__属性中查找。{/ p>

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

因此,当您说Foo instanceof Foo时,javascript VM将在Foo.__proto__中查找“Foo”。因为Foo是一个函数,Foo.__proto__Function.prototype(其中Function是函数的构造函数)。

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


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

答案 1 :(得分:1)

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

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

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

所以,仔细阅读代码:

function Foo() {}

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

Foo.prototype = Foo;

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

Foo.constructor = Foo

这实际上只在Foo上设置构造函数属性,它对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);