# Es5原型与继承

prototype：函数对象的原型对象（普通对象）

\__proto__:指向创建它的构造函数的原型对象

原型链的连接是实例（car1）和构造函数（Car）的原型对象（Car.prototype）之间，而不是实例和构造函数之间

## 构造函数式继承
+ 可以子传父
+ 引用类型的值相互独立
+ 父类构造函数重复执行，每次创建子类实例都会调用一次
+ 脱离于原型链，父类原型链上的方法属性无法继承

```javascript
function Car(name,price){
    this.name = name;
    this.price = [price];
}
Car.static = 'static';
Car.prototype.showName = function(){
    return this.name;
}
Car.prototype.tools={
    a:1,
    b:2
}
function ElectricCar(name,speed,price){
    Car.call(this,name,price);
    this.speed = speed;
}
let car1 = new ElectricCar('特斯拉',180,80);
let car2 = new ElectricCar('wei',160,90);
```

## 组合式继承

+ 可以子传父
+ 自身引用类型的值相互独立
+ 实现了对原型链上的方法参数的继承
+ 父类构造函数重复执行
+ 原型链上的引用类型的值还是浅拷贝

```javascript
function Car(name,price){
    this.name = name;
    this.price = [price];
    console.log(1);
}
Car.static = 'static';
Car.prototype.showName = function () {
    return this.name;
}
Car.prototype.tools = {
    a:1,
    b:2
}
function ExtendsFrom(sup,sub){
    function F(){}
    F.prototype=sup.prototype;
    sub.prototype = new F();
    sub.prototype.constructor = sub;
}
function ElectricCar(name,speed,price){
    Car.call(this,name,price);
    this.speed = speed;
}
ExtendsFrom(Car,ElectricCar);
let car1 = new ElectricCar('特斯拉',180,80);
let car2 = new ElectricCar('特斯拉2',160,90);
```

### 改进

+ 父类构造函数只执行一次

```javascript
function Car(name,price){
    this.name = name;
    this.price = [price];
    console.log(1);
}
Car.static = 'static';
Car.prototype.showName = function () {
    return this.name;
}
Car.prototype.tools = {
    a:1,
    b:2
}
function ElectricCar(name,speed,price){
    Car.call(this,name,price);
    this.speed = speed;
}
ElectricCar.prototype = Object.create(Car.prototype);
//ElectricCar.prototype.__proto__ == Car.prototype
ElectricCar.prototype.constructor = ElectricCar;
let car1 = new ElectricCar('特斯拉',180,80);
let car2 = new ElectricCar('特斯拉2',160,90);
```
