prototype
从构造函数看起
function Person () {
}
var person1 = new Person()
var person2 = new Person()
person1.name = '小明'
person2.name = '小红'
console.log(person1.name,person2.name) // 小明,小红
每一个构造函数都有一个prototype属性,这个属性指向的是这个构造函数构造出(new出)的对象的原型。即此例中person1、person2的原型。此时这两个对象的原型是相同的,他们的原型都为Person.prototype,这个原型是一个对象。
用一张图可以表示构造函数和原型的关系
注意:prototype为函数的属性
proto
function Person () {
}
var person1 = new Person()
var person2 = new Person()
person1.name = '小明'
person2.name = '小红'
console.log(person1.__proto__ === person2.__proto__) // true
console.log(person1.__proto__ === Person.prototype) // true
每一个构造函数new出来的对象上都有一个__proto__属性,这个属性指向的是构造函数的prototype属性,即Person.prototype
因此,我们的图现在变为如下形式
constructor
function Person () {
}
var person1 = new Person()
var person2 = new Person()
person1.name = '小明'
person2.name = '小红'
console.log(person1.__proto__ === person2.__proto__) // true
console.log(Person.prototype.constructor === Person) // true
cosole.log(Person.prototype.__proto__)
每个构造函数的prototype上都会带有一个constructor属性,这个属性叫构造器,它指向的是构造函数,如上例中的Person
此时的图变为
原型链
原型链,简单来说就是原型的原型。原型链是一条链式结构,它通过__proto__链接,一直到它指向Object.prototype的__proto__,即null。
我们知道对象的原型也是一个对象,因此,我们的原型对象也存在原型,在继承中,我们的原型对象的的原型指向它父级的原型,最后到Object.prototype的原型为止,此时它的原型指向null,即Object.prototype.proto === null
那么,此时,我们的图可以做如下的改动
其中,绿色的部分为原型链。