我在SO上发现了一些有趣的例子。其中包括与此article的链接。 它说:
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
。
答案 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.create
(MDN),它将一个对象作为其第一个参数,然后使用第一个对象作为其内部原型对象创建一个新对象。
答案 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);