JS的原型链
本文阐述了js中的prototype,constructor和proto之间的关系。
同时梳理了js如何实现继承的。
属性释义
-
prototype
prototype是JS中除了通过bind()生成的函数外所有function都具有的属性,其值为一个对象,对象里包含两个
值(proto和constructor)。作用是存储要共享的属性和方法。 - _proto_([[Prototype]])
proto是JS中每个对象都有的属性,其值指向了该对象构造函数的prototype。 -
constructor
constructor即构造函数,构造函数就是构造函数,其值为函数本身。
实例属性与类属性
- 类属性是指绑定到prototype上的属性,可以被所有通过该构造函数创建的实例继承。
- 实例属性是指绑定到this上的属性,可通过在构造函数内给对象init时绑定或者直接在
生成对象后绑定。其值是不可共享的。
属性之间的关系

//定义一个构造函数
var Foo = function(){}
此时[1] Foo.prototype = {constructor: Foo, __proto__:Object.prototype}
即:Foo.prototype.__proto__ === Object.prototype,
因为 Foo.prototype的值是个Object实例,
所以[3] {}.__proto__ = Object.prototype
console.log(Foo.prototype.__proto__ === Object.prototype
console.log(Foo.prototype.constructor === Foo)
var f1 = new Foo()
//此时[2] f1.__proto__ === Foo.prototype
console.log(f1.__proto__ === Foo.prototype)
Foo是我们自定义的构造函数,JS内置的构造函数也是同样的如Object,这里的Object是个构造函数
Object.prototype = {constructor: Object, __proto__: null}
console.log(Object.prototype.__proto__)
//null
为什么[4] Object.prototype.__proto__会是null呢?
Object.prototype 不是为 {} 吗, {}.__proto__不应该
是Object.prototype吗?而且我们自定义的构造函数就是这个样子呀!
如果设置Object.prototype.__proto__ = Object.prototype 那么,当查找一个不存在的属性时,JS
会从上级原型链去查这个属性,便会出现死循环,所以ES5规定Object.prototype.__proto__ = null
而且Object.prototype 指向的对象并不是继承自Object,即它不是Object的实例。
The value of the [[Prototype]] internal property of the Object prototype object is null, the value of the [[Class]] internal property is "Object", and the initial value of the [[Extensible]] internal property is true.
上面提到JS内置的构造函数Object,在JS中函数也是一种对象,即也存在Object.__proto__ 那么它指向谁呢?当然是Function.prototype了,因为
Function是js中所有function的构造函数,所以function Object(){}是Function的一个实例。
所以[7] Object.__proto__ === Function.prototype
console.log(Object.__proto__ === Function.prototype)
//true
JS中Function也是一个构造函数。
所以[9] Function.prototype = {constructor: Function, __proto__: Object.prototype},
[10] Function.__proto__ = Function.prototype
至此便是一个完整的JS原型链。
网友评论