原型/原型链

63 阅读2分钟

1. 构造函数创建对象

我们先使用构造函数创建一个对象

function Person() {}

let person = new Person()
person.name = 'xuexi'
console.log(person.name)// xuexi

这个例子里面Person是构造函数, 通过new Person创建一个实例

2. prototype

每个函数都一个prototype的属性:

function Person() {}

Person.name = 'xuexi'

let person1 = new Person()
let person2 = new Person()
console.log(person1.name) // xuexi
console.log(person2.name) // xuexi

函数的prototype属性指向一个对象, 这个对象正是调用这个构造函数而创建的实例对象, 也就是person1和person2的实例.

什么是原型呢? 你可以理解为: 每一个js对象(null除外)创建的时候都会与之关联另一个对象, 这个对象就是我们所说的原型, 每一个对象都会从原型上继承属性.

3. proto

每一个js对象(null除外),都有一个属性__proto__ , 这个属性指向该对象的原型

function Person() {}

let person = new Person()
console.log(Person.prototype === person.__proto__) // true

4. constructor

一个原型会指向一个构造函数, 每个原型都会有一个constructor属性指向该构造函数

function Person() {}

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

所以可以得到

function Person() {}

var person = new Person()

console.log(Person === Person.prototype.constructor) // true
console.log(Person.prototype === person.__proto__) // true

5. 实例与原型

当读取实例的属性时, 如果找不到, 就会查找与对象关联的原型中的属性, 如果还找不到, 就去找原型的原型, 一直找到最顶层.

function Person() {}

Person.prototype.name = 'xuexi'
var person = new Person()
person.name = 'haohao'
console.log(person.name) // haohao

delete person.name
console.log(person.name) // xuexi

当我们删除person.name的属性的时候, 在去打印这个属性, 它自己是没有这个属性的, 就会去找它自己的原型, 从原型上查找到name为xuexi

6. 原型的原型

如果原型上没找到?原型的原型又是什么?

var obj = new Object()

obj.name = 'xuexi'
console.log(obj.name) // xuexi

其实原型就是通过Object构造函数生成的.

7. 原型链

那么Object.prototype的原型呢?

答案是: null

// 打印下结果
console.log(Object.prototype.__proto__ === null) // true

所以查找到Object.prototype的时候就可以停止查找了;