当声明一个对象,那么这个对象一定要找到一个公用的属性,如果没有公用的属性,那么这个对象就没啥用了,除了存数据就没有其他的价值了,有了公用属性之后,就可以调用各种API。
所有对象都有 toString
和 valueOf
属性,那么我们是否有必要给每个对象一个 toString
和 valueOf
呢?
明显不需要。
JS 的做法是把 toString
和 valueOf
放在一个对象里(暂且叫做公用属性组成的对象)
然后让每一个对象的 __proto__
存储这个「公用属性组成的对象」的地址。
原型就是公用属性的意思。
下图中公用属性通过__proto__
串起来的像链一样的路线就是原型链。
浏览器一开始就在内存里把原型给初始化好了。如下:
prototype原型
var a = {}
// undefined
var b = {}
// undefined
a === b
// false
a.toString === b.toString
// true
上面代码能看出,a
和b
是两个完全不一样的对象,严格相等运算返回的结果都是false
,但是两者的toString
是完全一样的,因为两个对象的toString
属性都存在同一个公用属性里。(也就是Object
的原型里)
var a = {}
// undefined
Object.prototype
// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
a.__proto__ === Object.prototype
// true
上面代码能看出,Object.prototype
是Object
的公用属性的引用(不引用就要被回收了),a.__proto__
也是Object
的公用属性的引用,所以严格相等返回的是true
(必须要用公用属性)。
var n1 = new Number(1)
// undefined
n1.__proto__ === Number.prototype
// true
n1.__proto__.__proto__ === Object.prototype
// true
上列代码表示n1
是一个对象,但是对象里面是一个数值1
,所以n1.__proto__
引用的公共属性跟Number.prototype
引用的是同样的属性,Number.prototype
引用的公用属性本身里面也有个__proto__
引用Object.prototype
引用到的公共属性(具体可以看文章开头两幅图来理解),所以n1.__proto__.__proto__
是与Object.prototype
严格相等的,因为引用的都是同一个公共属性。
网友评论