ES6 Class 与 ES5 构造函数对比(Babel编译)

1,367 阅读2分钟

Class

User类被编译以后转化为构造函数。被编译后生成了_classCallCheck,_instanceof方法。

class User{

}
const user = new User();
console.log(user); // {}

//↑↑↑↑↑↑↑↑↑↑↑↑↑ ES6 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//↓↓↓↓↓↓↓↓↓↓↓↓↓ ES5 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓

"use strict";

function _instanceof(left, right) {
  if (
    right != null &&
    typeof Symbol !== "undefined" &&
    right[Symbol.hasInstance]
  ) {
    return right[Symbol.hasInstance](left);
  } else {
    return left instanceof right;
  }
}

function _classCallCheck(instance, Constructor) {
  if (!_instanceof(instance, Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

var User = function User() {
  _classCallCheck(this, User);
};

var user = new User();
console.log(user); // {}

普通属性

User类有name、age、address三个属性,name、age属性采用Object.defineProperty的方式定义属性。 虽然与address赋值方式不一样,但是最终的效果是一致的。

注意:name、age不是定义在原型上的属性 实例属性新写法

class User{
    name = "jason";
    age = 18;
    constructor(){
        this.address = "shanxi";
    }
}

const user = new User();
console.log(user); //{ name: 'jason', age: 18, address: 'shanxi' }

//↑↑↑↑↑↑↑↑↑↑↑↑↑ ES6 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//↓↓↓↓↓↓↓↓↓↓↓↓↓ ES5 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}

var User = function User() {
  _classCallCheck(this, User);

  _defineProperty(this, "name", "jason");

  _defineProperty(this, "age", 18);

  this.address = "shanxi";
};

以下代码省略了_defineProperty,_classCallCheck,_instanceof等公用的方法。

普通函数

sayName函数在构造函数的原型上 调用了_defineProperties(Constructor.prototype, protoProps);

class User{
  name = "jason";
  sayName(){
    console.log(this.name);
  }
}

const user = new User();
user.sayName()

//↑↑↑↑↑↑↑↑↑↑↑↑↑ ES6 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//↓↓↓↓↓↓↓↓↓↓↓↓↓ ES5 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓

function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}

function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  return Constructor;
}

var User =
  (function() {
    function User() {
      _classCallCheck(this, User);

      _defineProperty(this, "name", "jason");
    }

    _createClass(User, [
      {
        key: "sayName",
        value: function sayName() {
          console.log(this.name);
        }
      }
    ]);

    return User;
  })();

var user = new User();
user.sayName()

箭头函数

箭头函数在编译后对this做了绑定

class User{
  name = "jason";
  sayName = () => {
    console.log(this.name);
  }
}

//↑↑↑↑↑↑↑↑↑↑↑↑↑ ES6 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//↓↓↓↓↓↓↓↓↓↓↓↓↓ ES5 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓

var User = function User() {
  var _this = this;

  _classCallCheck(this, User);

  _defineProperty(this, "name", "jason");

  _defineProperty(this, "sayName", function() {
    console.log(_this.name);
  });
};

静态属性

静态属性作为构造函数的一个属性存在

class User{
  static name = "jason";
}

//↑↑↑↑↑↑↑↑↑↑↑↑↑ ES6 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//↓↓↓↓↓↓↓↓↓↓↓↓↓ ES5 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓

var User = function User() {
  _classCallCheck(this, User);
};

//省略_defineProperty方法源码
//静态属性 被编译后 第一个参数是User,而普通属性则是this
_defineProperty(User, "name", "jason");

静态方法

静态方法sayName作为构造函数的一个属性存在

class User {
  name = "jason"
  static sayName() {

  }
}

//↑↑↑↑↑↑↑↑↑↑↑↑↑ ES6 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑
//↓↓↓↓↓↓↓↓↓↓↓↓↓ ES5 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓

function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}

function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  return Constructor;
}
var User =
/*#__PURE__*/
function () {
  function User() {
    _classCallCheck(this, User);

    _defineProperty(this, "name", "jason");
  }
  //静态函数编译后,第二个参数设置为null
  _createClass(User, null, [{
    key: "sayName",
    value: function sayName() {}
  }]);

  return User;
}();