JavaScript 基础知识整理之原型和原型链

397 阅读2分钟

原型

什么是原型

我们可以这样理解:每个JavaScript对象(除了null)被创建的时候都会和另一个对象所关联,那么这个对象就是我们所说的原型,每一个对象都会从原型上继承属性

prototype

function Car() {}
Car.prototype.name = '大众'
let car1 = new Car()
let car2 = new Car()
console.log(car1.name, car2.name) // 大众 大众

每个函数都会有一个prototype属性,如上面代码所示。函数的prototype指向了一个对象,这个对象是调用构造函数Car所创建出实例car1,car2的原型

proto_

每个JavaScript对象(除了null)都会有一个属性_proto_,该属性指向对象的原型。如下代码所示

function Car() {}
let car = new Car()
car._proto_ === Car.prototype // true

constructor

每一个原型都有一个cunstructor属性指向他的关联构造函数。

function Car() {}
console.log(Car.prototype.constructor === Car) //true

所以:

function Car() {}
let car = new Car()
car._proto_ == Car.prototype //true
Car.prototype.constructor == Car //true
Object.getPrototypeOf(car) === Person.prototype //true

关系图如下:

原型与实例

当读取实例的属性的时候,如果找不到就会去该实例关联的原型中去查找。如果还是找不到,就去找原型的原型,一直到最顶层为止。如下代码所示:

function Car() {}
Car.prototype.name = '大众';

var car = new Car();

car.name = '迈腾';
console.log(car.name) // 迈腾

delete car.name;
console.log(car.name) // 大众

在上述代码中,我们给实例car添加了name属性,当我们打印car.name的时候,结果自然是 迈腾。然后我们删除car的name属性,再次打印时:首先去car对象中去查找,没有找到name属性,就回去car的原型(就是car.proto,也就是Car.prototype)去查找。结果找出了name,所以打印出 大众。那么万一Car.prototype中也没有那么属性?接下来又是如何进行的?

原型的原型

原型对象就是通过 Object 构造函数生成的,结合之前所讲,实例的 proto_ 指向构造函数的 prototype ,如下图所示

原型链

Object.prototype.__proto__ === null // true

Object.prototype.proto_ 的值为 null 跟 Object.prototype 没有原型,其实表达了一个意思。所以查找属性的时候查到 Object.prototype 就可以停止查找了