Function object __proto__ and prototype property
我正试图找出我编写的函数的原型链
1 2 3 4 5 6 7 8 | function Animal(voice) { this.voice = voice|| 'meaw' } Animal.prototype.speak =function() { console.log(this.voice); } |
我知道动物函数有一个原型属性,指向它的原型对象。它的原型对象有指向后面的构造函数和指向对象对象原型的原型属性
我知道每个函数对象都继承自函数的对象原型,并且继承自对象的对象原型,包括uu proto_uuuu属性。现在,当我进一步研究它的时候,我发现函数的对象原型和属性链接到同一个原型对象。
1 2 | console.log(Animal.__proto__.constructor.__proto__ == Animal.__proto__.constructor.prototype ); //true console.log(Animal.__proto__.constructor.__proto__ == Animal.__proto__); //true |
然后我做了进一步的测试来证明它
1 2 3 4 | Animal.__proto__.constructor.__proto__.test = 28; console.log(Animal.__proto__.constructor.__proto__.test); // prints 28 console.log(Animal.__proto__.test); //prints 28 |
这意味着它的原型和它继承的原型是相同的。为什么会这样?
你已经知道
1 2 | Function.prototype.constructor.__proto__ == Function.prototype.constructor.prototype // true Function.prototype.constructor.__proto__ == Function.prototype // true |
现在,
1 2 | Function.__proto__ == Function.prototype // true Function.__proto__ == Function.prototype // true |
现在,考虑到
这就是你的测试所证实的,就像你基本上所做的那样。
1 2 3 4 | Function.__proto__.test = 28; Function.__proto__.test // 28 Function.prototype.test // 28 |
是的,
1 | Animal.__proto__ === Function.prototype //true |
现在,如果用
1 | Function.prototype.constructor.__proto__ === Function.prototype |
为什么会这样?
如果您想知道为什么
The Function constructor is itself a built-in function object. The
value of the [[Prototype]] internal slot of the Function constructor
is %FunctionPrototype%, the intrinsic Function prototype object
(19.2.3).
The value of Function.prototype is %FunctionPrototype%, the intrinsic
Function prototype object (19.2.3).
因此,由于
1 2 | var func = new Function() Function.__proto__ === func.__proto__ |
I found out that Function's object prototype and proto property links to the same prototype object.
您正在混合"原型属性"和"原型对象"。
1 2 3 | function Animal(){} let animal = new Animal(); animal.__proto__ = Animal.prototype; |
实际上,
您的困惑是由于
1 2 | Function.prototype === Function.__proto__; // true typeof Function.prototype; //"function" |
这就是JavaScript查找链的工作原理。
首先注意到
1 2 | Animal.__proto__ === Function.prototype \\true Animal.__proto__.constructor === Function \\true |
因为对于任何函数
那么问题就变成了,
1 | Function.__proto__ === Function.prototype \\true |
这有点奇怪,因为这两个属性通常不相同。
通常,当
1 | a.__proto__ === A.prototype \\true |
实例的
1 | Function.constructor === Function //true |
现在更有意义了。
现在我们回顾一下这个问题。
1 | Animal.__proto__.constructor.__proto__.test = 28; |
等同于:
1 | Function.__proto__.test = 28; |
等同于:
1 | Function.prototype.test = 28; |
因此,现在很明显,这两个
1 | Animal.__proto__ === Function.prototype \\ture |
就像我们刚开始说的。