原型和原型链

153 阅读2分钟

prototype

prototype是函数特有的属性,每个函数的prototype属性指向了一个对象,这个对象正是调用该构造函数而建立的实例的原型。下面例子中person1person2就是Person的实例。

举个例子:

function Person(){}
Person.prototype.name = 'Tom';
var person1 = new Person();
var person2 = new Person();
console.log(person1) //===> Tom
console.log(person2) //===> Tom

什么是原型?

每个一JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个就像就是我们所说的原型,每个对象都会从原型** 继承 ** 属性。

让我们用一张图表示构造函数和实例原型之间的关系:

上图中Person.prototype 表示实例原型。

_proto_

每一个JavaScript对象(除了null)都具有的一个属性,叫做_proto_,这个属性会指向该对象的原型

举个例子:

function Person(){}
var person = new Person();
console.log(person._proto_ === Person.prototype); // ture

更新关系图:

实例对象和构造函数都可以指向原型。

重要提示:

绝大部分的浏览器都支持这个非标准的方法访问原型,然而它并不存在于Proson.prototype中,实际上,它都是来自于Object.prototype,与其说是一个属性,不如说是一个getter/setter,当使用obj._proto_ 时,可以理解成返回了Objiect.getPrototypeOf(obj)

constructor

原型指向构造函数倒是有的,这就要讲到第三个属性:constructor,每个原型都有一个 constructor 属性指向关联的构造函数。

function Person() {

}
console.log(Person === Person.prototype.constructor); // true

更新关系图如下:

根据上述可以得出一下结论:

functino Person(){}
var person = new Person()
console.log(person ._proto_ === Person.prototype) // true
console.log(person.constructor === Person) // true
console.log(Person.prototype.constructor === Person) // true
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

需要注意:

其实person中并没有constructor属性,当不能读取constructor属性时,会从person的原型也就是Person.prototype中读取,也就是说。

person.constructor === Person.prototype.constructor

实例的原型

当读取实例的属性时,如果找不到就会查找与对象关联的原型中的属性,如果还是查不到,就去找原型的原型。也就是顺着原型链查找,直到顶层为止。

举个例子:

fuction Person(){}
Person.prototype.name = 'Tom';
var person = new Person()
person.name = 'kelly'

console.log(person.name) // 'kelly'

delete person.name

console.log(person.name) // 'Tom'

这个例子可以说明当个实例person添加了name属性时,打印person.name的时候,结果就是kelly。当删除personname属性时,打印person.name时就会顺着person._proto_(原型链)去查找。正好Perosn.prototype(person的原型)中有name属性,返回结果Tom

如果原型中没有查找到,就会查找原型的原型。

原型的原型

原型也是对象,既然是对象就会有原型。

原型对象就是通过Object构造函数生产的,实例的_proto_指向构造函数的prototype

跟新关系图如下:

原型链

上图中相互关联的原型组成的链状结构就是原型链。也就是黄色的这条线。

最终指向null

最后 最后

来一张可以说明一起的图例: