es6的class

54 阅读2分钟

es6 class构造

class是es6提出来的概念,要想实现类似这种类的概念,在es6之前是通过原型的方式来实现的。

在es5中:

function Person() {
    // 构造函数体
}
Person.prototype.sayHi = function() {
    
};
Person.prototype.play = function() {
    
};

es6中:

class Person {
    constructor() {
        // 构造函数体
    }
    // 下面这个sayHi和play就是Person.prototype上面的一个方法
    sayHi() {};
    play() {};
}

小结:

  1. 在ES5中,向原型上添加方法是:函数.prototype.方法名 = function() {};
  2. 在ES6中的对象的属性都是写在constructor关键字里面,方法也都是在原型身上。

es6 继承的底层实现原理

ES6类的底层还是通过构造函数去创建的。

// es6 Parent类实现
class Parent {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    speakSomething() {
        console.log("I can speak chinese");
    }
}

// 转换为
var Parent = function() {
    function Parent(name, age) {
        _classCallCheck(this, Parent); // 判断实例Parent instanceof Parent(函数)是否为true
        this.name = name;
        this.age = age;
    }
    
    // 此方法通过使用Object.defineProperty为function Parent 的prototype添加属性值
    _createClass(Parent, [{
        key: "speakSomething",
        value: function speakSomething() {
            console.log("I can speek chinese");
        }
    }]);
    
    return Parent;
}();

小结:

  1. 调用_classCallCheck方法判断当前函数调用前是否有new关键字
  2. 将class内部的变量和函数赋给this
  3. 执行constructor内部的逻辑
  4. return this(构造函数默认在最后我们做了)

ES6的继承实现

// 定义子类,继承父类
class Child extend Parent {
    static width = 18;
    constructor(name, age) {
        super(name, age);
    }
    coding() {
        console.log("I can code JS");
    }
}
// 转化为
var Child = function (_Parent) {
    _inherits(Child, _Parent);
    function Child(name, age) {
        _classCallCheck(this, child);
        return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, name, age));
    }
    _createClass(Child, [{
        key: 'coding',
        value: function coding() {
            console.log("I can code JS");
        }
    }]);
    
    return Child;
}(Parent);

小结:

1. 调用_inherits函数继承父类的prototype
function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
  }
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: { value: subClass, enumerable: false, writable: true, configurable: true }
  });
  if (superClass)
    Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

(1)检验父构造函数
(2)典型的寄生继承:用父类构造函数的prototype创建一个空对象,并将这个对象指向子类构造函数的prototype。
(3)将父构造函数指向子构造函数的__proto__

2. 用一个闭包保存父类引用,在闭包内部做子类构造逻辑
3. 用new检查
4. 用当前this调用父类构造函数
5. 将行子类class内部的变量和函数赋给this
6. 执行子类constructor内部的逻辑