02-ES6中class用法及底层实现原理

166 阅读1分钟

类的继承

function Animal () {
   this.type = '哺乳类'
}
Animal.prototype.eat = function () {}
function Tiger () {
   Animal.call(this) // 继承Animal私有属性和方法
}
// 继承Animal公有属性和方法的方式一
Object.setPrototypeOf(Tiger.prototype, Animal.prototype)
let tiger = new Tiger()

// 继承Animal公有属性和方法的方式二
Tiger.prototype = Object.create(Animal.prototype, {constructor: {value: Tiger}})
let tiger = new Tiger()
class Animal {
    constructor (type) {
       this.type = type
    }
    eat () {
       console.log('eat')
    }
    static flag = 'animal'
    static fn () {
        return 'fn'
    }
}

class Tiger extends Animal {
    constructor (type) {
        super(type)
    }
    static fn () {
        return super.fn()
    }
    eat () {
        super.eat()
    }
}
let tiger = new Tiger('哺乳类')
tiger.eat()
console.log(Tiger.flag)

ES6中的语法

class Animal {
    constructor (type) {
        this.type = type
    }
    a = 1 // es7语法
    eat () {
        console.log('eat', this)
    }
    get a() { return 100 }
    set a() {}
    static say () {console.log('say')}
    static get a () {return 'hello'}
    static n = 200
}
let animal = new Animal('哺乳类')
let eat = animal.eat
eat() 

class创建的类和普通函数创建的类的区别:class创建的类不能作为普通函数执行

class 的底层实现原理

转换前

class Parent {
   constructor (a) {
       this.filed1 = a
   }
   filed2 = 2
   func1 = function () {}
}

转换后

function _classCallCheck(instance, Constructor) {
 // instanceof 检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}
var Parent = function Parent(a) {
  _classCallCheck(this, Parent);

  this.filed2 = 2;

  this.func1 = function () { };

  this.filed1 = a;
}

可见class的底层依然是构造函数:

  1)调用_classCallCheck方法判断当前函数调用前是否有new关键字

    构造函数执行前有new关键字,会在构造函数内部创建一个空对象,将构造函数的prototype指向这个空对象的__prpto__,并将this指向这个空对象。如上,_classCallCheck中:this instanceof Parent,返回true。

    若构造函数前面没有new则构造函数的prototype不会出现在this的原型链上,返回false

  2)将class内部的变量函数赋值给this

  3)执行constructor内部的逻辑

  4)return this(构造函数默认在最后帮我们做了这一步)