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属性- 继承自同一原型的两个实例,属于同一类
Array与Array.prototype是两个不同的对象
3、构造函数执行的流程
- 创建一个新对象
- 将这个对象的原型指向构造函数的 prototype 属性
- 将构造函数的作用域赋值给新对象 (因此 this 指向这个新对象)
- 执行构造函数中的代码 (给新对象添加属性或方法,推荐通过使用原型给对象添加方法)
- 返回新对象
// 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