原型与原型链

当声明一个对象,那么这个对象一定要找到一个公用的属性,如果没有公用的属性,那么这个对象就没啥用了,除了存数据就没有其他的价值了,有了公用属性之后,就可以调用各种API。
所有对象都有 toStringvalueOf属性,那么我们是否有必要给每个对象一个 toStringvalueOf 呢?
明显不需要。
JS 的做法是把 toStringvalueOf 放在一个对象里(暂且叫做公用属性组成的对象)
然后让每一个对象的 __proto__存储这个「公用属性组成的对象」的地址。
原型就是公用属性的意思。
下图中公用属性通过__proto__串起来的像链一样的路线就是原型链。

原型链

浏览器一开始就在内存里把原型给初始化好了。如下:


prototype原型
var a = {}
// undefined
var b = {}
// undefined
a === b
// false
a.toString === b.toString
// true

上面代码能看出,ab是两个完全不一样的对象,严格相等运算返回的结果都是false,但是两者的toString是完全一样的,因为两个对象的toString属性都存在同一个公用属性里。(也就是Object的原型里)

var a = {}
// undefined
Object.prototype
// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
a.__proto__ === Object.prototype
// true

上面代码能看出,Object.prototypeObject的公用属性的引用(不引用就要被回收了),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严格相等的,因为引用的都是同一个公共属性。

你可能感兴趣的:(原型与原型链)