ES6 Class 與 ES5 構造函數對比

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;
}();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章