原型关系图
__proto__ 和 prototype 的区别
__proto__是对象的属性prototype是函数的属性
function Foo() {}
let a = new Foo()
在我们使用new调用一个函数时,最后都会构造一个内置的对象叫做Foo.prototype
所以的a它是一个{}对象, 这个对象的原型访问是: a.__proto__
现在可以知道prototype是一个函数的属性,__proto__是方便给赋值后的变量调用的一个对象的原型属性
Object的原型
Object.prototype // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
let obj = {}
obj.__proto__ === Object.prototype // true
obj.__proto__.__proto__ === null // true Object最终的原型指向是null
Number的原型
Number.prototype // Number {0, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, toPrecision: ƒ, …}
let n1 = new Number(1)
n1.__proto__ === Number.prototype //true
n1.__proto__.__proto__ === Object.prototype // true
Boolean的原型
Boolean.prototype // Boolean {false, constructor: ƒ, toString: ƒ, valueOf: ƒ}
let b1 = new Boolean(1)
b1.__proto__ === Boolean.prototype // true
b1.__proto__.__proto__ === Object.prototype //true
String的原型
String.prototype //String {"", constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ, …}
let s1 = new String('1')
s1.__proto__ === String.prototype //true
s1.__proto__.__proto__ === Object.prototype //true
小结
可以很清楚的看出,Number\String\Boolean的原型都指向内置的object的原型Object.prototype这个对象。
所以Number\String\Boolean也同时拥有Object.prototype的属性。
而Object.prototype的原型最终是指向null;
Object.prototype.__proto__; // null
const nil = Object.prototype.__proto__;
nil === null; // true