ES6 —— 继承
@[TOC](文章目录)
---
#### 一、call() 方法的使用
1. call():调用这个函数,并且修改函数运行时的 this 指向。
> 语法:`fun.call(thisArg, arg1, arg2, ...)`
> 1. `this.Arg`:当前调用函数 this 的指向对象
> 2. `arg1, arg2`:传递的其他参数
```javascript
//ES5 直接调用
function fn(){
console.log('I want to eat.')
console.log(this) //this 指向 window
}
fn()
```

```javascript
// ES6 call() 方法
function fn(){
console.log('I want to eat.')
console.log(this)
}
fn.call()
```

```javascript
//ES6 的 call()
// call 方法
function fn(x, y){
console.log('I want to eat.')
console.log(this) //this 指向 o 这个对象
console.log(x + y)
}
let o = {
name: '不易'
}
// 2.call() 可以改变 fn 的 this 指向 此时这个函数的 this 就指向了o 这个对象
fn.call(o, 1 , 2)
```

#### 二、借用构造函数继承父类型属性
1. 核心原理:通过 `call()` 把父类型的 `this` 指向子类型的 `this`,这样就可以实现子类型继承父类型的属性。
```javascript
// 1.父构造函数
function Father(uname, age){
// this 指向父构造函数的对象实例
this.uname = uname
this.age = age
}
// 2.子构造函数
function Son(uname, age, score){
// this 指向子构造函数的对象实例
Father.call(this, uname, age) //把父亲的 this 改成 孩子的 this
this.score = score
}
let son = new Son('张三', 18, 100)
console.log(son)
```

#### 三、利用原型对象继承方法

```javascript
// 1.父构造函数
function Father(uname, age){
// this 指向父构造函数的对象实例
this.uname = uname
this.age = age
}
Father.prototype.money = function(){
console.log('2w one month')
}
// 2.子构造函数
function Son(uname, age, score){
// this 指向子构造函数的对象实例
Father.call(this, uname, age) //把父亲的 this 改成 孩子的 this
this.score = score
}
// Son.prototype = Father.prototype 这样直接赋值有问题 如果修改了子原型对象 父原型对象也会跟着变化
// 如果利用对象的形式修改了原型对象 别忘了利用 constructor 指回原来的构造函数
// 由于 Son.prototype = new Father() 实例对象覆盖了Son.prototype对象 所以需要加一个 constructor
Son.prototype.constructor = Son
Son.prototype = new Father()
// 这个是子构造函数专门的方法
Son.prototype.exam = function(){
console.log('I need to exam')
}
let son = new Son('张三', 18, 100)
console.log(son)
console.log(Father.prototype)
console.log(Son.prototype.constructor)
```

#### 四、类的本质
1. 类的本质是一个函数。
> 可以简单的理解为:类就是构造函数的另外一种写法。
```javascript
class Star{
}
console.log(typeof Star) //function
```
2. 类有原型对象 `prototype`。类所有方法都定义在类的 `prototype` 属性上。
```javascript
class Star{
}
console.log(Star.prototype)
```

3. 类原型对象 prototype 也有 constructor 指向类本身。
```javascript
class Star{
}
console.log(Star.prototype.constructor)
```

4. 类可以通过原型对象方法添加对象。
```javascript
class Star{
}
Star.prototype.sing = function(){
console.log('无名的人')
}
let a = new Star('毛不易')
console.log(a)
```

5. 类创建的实例对象有 `__proto__` 原型指向类的原型对象。
```javascript
class Star{
}
Star.prototype.sing = function(){
console.log('无名的人')
}
let a = new Star('毛不易')
console.log(a.__proto__ === Star.prototype) //true
```
6. ES6 的类其实就是语法糖。
> 语法糖:一种便捷方法。简单理解,有两种方法可以实现同样的功能,但是一种写法更加清晰、方便,那这个方法就是语法糖。