JavaScript 中的原型链与继承

249 阅读2分钟

JavaScript 中的原型链与继承

1、原型链

JavaScript 是一种动态语言,并没有类似于 Java 中的类 Class,只有一个个的对象,对象之间通过原型链连接起来 (ES6 中的 Class 只是语法糖,其实质还是通过原理链来实现继承)

JavaScript 只有一种结构:对象。每个实例对象(object )都有一个私有属性(称之为 proto)指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象 ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

遵循ECMAScript标准,someObject.[[Prototype]] 符号是用于指向 someObject的原型。从 ECMAScript 6 开始,[[Prototype]] 可以通过Object.getPrototypeOf()和Object.setPrototypeOf()访问器来访问。这个等同于 JavaScript 的非标准但许多浏览器实现的属性 proto

原型链

每个实例对象都有一个私有属性__proto__,指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象,层层向上直到一个对象的原型对象为 null 为止。

function Car () {}
Car.prototype.show = () => console.log('car');

let car = new Car();
car.show(); // output ---> 'car'

let specialCar = Object.create(car);
// specialCar 以 car 为原型
specialCar.show(); // output ---> 'car'

specialCar.__proto__ === car;
car.__proto__ === Car.prototype;
Car.prototype.__proto__ === Object.prototype;
Object.prototype.__proto__ === null;

// 所以上面示例的原型链指向为
// specialCar ---> car ---> Car.prototype ---> Object.prototype ---> null

2、 原型引用 __proto__ 与原型对象 prototype

  • __proto__ 为对象指定原型 (在某些浏览器上只读,不建议使用)
  • prototype 为对象的类的原型的引用,普通对象没有 prototype 属性,只有构造函数有 prototype 属性
  • 继承自同一原型的两个实例,属于同一类
  • ArrayArray.prototype 是两个不同的对象

3、构造函数执行的流程

  1. 创建一个新对象
  2. 将这个对象的原型指向构造函数的 prototype 属性
  3. 将构造函数的作用域赋值给新对象 (因此 this 指向这个新对象)
  4. 执行构造函数中的代码 (给新对象添加属性或方法,推荐通过使用原型给对象添加方法)
  5. 返回新对象
// Student 继承自 Person
function Person () {};
Person.prototype.funA = () => {};
function Student () {
    console.log(this);
};
Student.prototype.funB = () => {};

Student.prototype = new Person();
Student.prototype.constructor = Student;

new Student();

4、原型链判断

原型链

Array.__proto__ === Function.prototype;
Function.prototype.__proto__ === Object.prototype;
Object.prototype.__proto__ === null;

[].__proto__ === Array.prototype;
Array.prototype === Object.prototype;

{}.__protype === Object.prototype;
Object.__proto__ === Function.prototype;
Function.__proto__ === Function.prototype;
Function.prototype.__proto__ === Object.prototype;

// 判断实例对象
Object instanceof Function; // true
Function instanceof Function; // true
Function instanceof Object; // true

3、参考