1、每个对象
都有一个__proto__属性
2、每个函数
都会有prototype属性
3、生成对象
时,对象
的__proto__
属性指向函数
的prototype
属性。
现在存在一个问题,如何解释下面情况:
Object.__proto__ === Function.prototype
=> true
Function.__proto__ === Function.prototype
=> true
...
在JavaScript中,万物皆对象。构造函数作为对象拥有__proto__属性,构造函数作为函数拥有prototype属性。构造函数作为Function构造函数函数实例化出来的,那么他的__proto__属性就会继承Function构造函数的prototype属性。
所以第一个是true。
Function构造函数作为一个对象,也应该拥有一个__proto__属性,Function对象也应该会继承Function的prototype属性,所以第二条也是true。
总结:对象的__proto__属性继承自生成他的函数的prototype属性(不手动修改的情况下)。
那么函数的prototype到底是什么?
function a(){}
a.prototype
=>{constructor: ƒ}
constructor: ƒ aaa()
__proto__: Object
a.prototype.constructor === a
=> true
a.prototype.__proto__ === Object.prototype
=> true
一般函数的prototype是一个类型为"Object"的对象,拥有两个属性:constructor和__proto__。其中constructor就是指向函数本身,__proto__指向生成该Object对象的构造函数就是Object构造函数。
但是
Function.prototype.__proto__
=> {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
Function.prototype.__proto__ === Object.prototype
=> true
所有函数都是由Function构造函数实例化,所以所有函数的__proto__属性都是指向Function.prototype。但是Function作为一个函数,那么Function.prototype.__proto__应该也是指向Function.prototype的