我试图找出我写的函数的原型链
function Animal(voice)
{
this.voice = voice|| 'meaw'
}
Animal.prototype.speak =function() {
console.log(this.voice);
}
我知道Animal函数有一个原型属性,指向它的原型对象。它的原型对象有指向后面的构造函数和指向Object对象原型的 __ proto __ 属性
我知道每个函数对象都继承自 Function 的对象 prototype ,并且继承自Object的对象 prototype ,包括 __ proto__ 属性。现在,当我进一步调查它时,我发现函数的对象原型和 __ proto __ 属性链接到同一个原型对象。
console.log(Animal.__proto__.constructor.__proto__ == Animal.__proto__.constructor.prototype ); //true
console.log(Animal.__proto__.constructor.__proto__ == Animal.__proto__); //true
然后我做了一些进一步的测试来证明它
Animal.__proto__.constructor.__proto__.test = 28;
console.log(Animal.__proto__.constructor.__proto__.test); // prints 28
console.log(Animal.__proto__.test); //prints 28
这意味着它是原型,它的原型继承是相同的。为什么这样设置的原因?
答案 0 :(得分:2)
您已经知道Object.getPrototypeOf(Animal)
(或Animal.__proto__
)是Function.prototype
object。所以,让我们放弃Animal
事物,然后用Function.prototype
重复你的等式:
Function.prototype.constructor.__proto__ == Function.prototype.constructor.prototype // true
Function.prototype.constructor.__proto__ == Function.prototype // true
现在,.constructor
的{{1}}属性(与所有明确定义的原型对象一样)指向其各自的构造函数Function
constructor function。所以我们已经
Function.prototype
现在,鉴于Function.__proto__ == Function.prototype // true
Function.__proto__ == Function.prototype // true
是一个函数,只有它像所有其他函数一样继承自Function
才有意义。
这是您的测试确认的内容,正如您基本上所做的那样
Function.prototype
是的,Function.__proto__.test = 28;
Function.__proto__.test // 28
Function.prototype.test // 28
和Function.test
现在也会产生Animal.test
。
答案 1 :(得分:0)
这就是Javascript查找链的工作原理。
首先请注意
pip install --upgrade pip
因为任何函数Animal.__proto__ === Function.prototype \\true
Animal.__proto__.constructor === Function \\true
,
A
然后问题变成了A.prototype.constructor === A
的{{1}}属性是什么?它是__proto__
。
Function
这有点奇怪,因为这两个属性通常不一样。
通常,Function.prototype
Function.__proto__ === Function.prototype \\true
实例的a = new A();
属性等于其构造函数的a.__proto__ === A.prototype \\true
;
但请注意,每个函数都是__proto__
的实例,而prototype
本身也是一个函数。 Function
是它自己的构造函数!
Function
现在更有意义了。
现在我们回顾一下这个问题。
Function
等同于:
Function.constructor === Function //true
等同于:
Animal.__proto__.constructor.__proto__.test = 28;
现在很清楚,两个Function.__proto__.test = 28;
打印出相同的内容,因为:
Function.prototype.test = 28;
正如我们在一开始所说的那样。
答案 2 :(得分:0)
我发现Function的对象原型和 proto 属性链接到同一个原型对象。
你正在混合"原型属性"和"原型对象"。
.prototype
是构造函数的属性。每当调用构造函数时,它都会创建原型对象设置为Constructor.prototype
的对象。
function Animal(){}
let animal = new Animal();
animal.__proto__ = Animal.prototype;
事实上,__proto__
属性只是在调用Object.prototype
的{{1}}上定义的getter。
您的混淆是由Object.getPrototypeOf
(所有函数都是Object.getPrototypeOf(Animal) === Function.prototype
的实例)和函数构造函数/原型被扭曲的事实引起的。
Function
答案 3 :(得分:0)
Animal
是一个函数,就像所有函数一样(除非你修改它),它链接回Function.prototype
对象。所以:
Animal.__proto__ === Function.prototype //true
现在,如果我们将Animal.__proto__
替换为Function.prototype
,我们就会得到:
Function.prototype.constructor.__proto__ === Function.prototype
为什么? Function.prototype.constructor
链接回其构造函数,即Function
构造函数。所以这实际上意味着:
Function.__proto__ === Function.prototype
如果您想知道为什么Function.__proto__
和Function.prototype
共享相同的值,请查看规范。
Function构造函数本身就是一个内置函数对象。该 Function构造函数的[[Prototype]]内部槽的值 是%FunctionPrototype%,内在的Function原型对象 (19.2.3)。
The Function.prototype
property shares the same value:
Function.prototype的值是%FunctionPrototype%,内在的 函数原型对象(19.2.3)。
因此,由于Function
和new Function()
的结果都是函数,因此它们共享相同的[[Prototype]]
:
var func = new Function()
Function.__proto__ === func.__proto__