參考文章:阮一峯 Class 的基本語法es6
JavaScript語言的傳統方法是經過構造函數定義並生成新對象,這種寫法和傳統的面嚮對象語言差別較大。因此,ES6引入了Class這個概念做爲對象的模板。
class能夠看做只是一個語法糖,它的絕大部分功能,ES5 均可以作到。數組
// es5 中的構造函數 function Person(name, age) { this.name = name; this.age = age; } Person.prototype.toString = function () { return '(' + this.name + ',' + this.age + ')'; } var p = new Person('xiaoMing', 18); // es6 經過class實現 class Person { constructor(name, age) { this.name = name; this.age = age; } toString() { return '(' + this.name + ',' + this.age + ')'; } } var p = new Person('xiaoMing', 18);
上面代碼定義了一個「類」,能夠看到裏面有一個constructor方法,這就是構造方法,而this關鍵字則表明實例對象。也就是說,ES5 的構造函數Point,對應 ES6 的Point類的構造方法。babel
class Person { // ... } typeof Person // "function" Person === Person.prototype.constructor // true
上面代碼代表,類的數據類型就是函數,類自己就指向構造函數。函數
es6中的class的具體使用能夠參考阮一峯Class 的基本語法。this
咱們如今看下es6中的class是怎麼經過es5語法實現的,讓我藉助babel來一步一步看一下class轉換成es5的代碼es5
先添加一個類prototype
// es6 class Person { } // 經過babel轉換成的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; } } // 檢查聲明的class類是否經過new的方式調用,不然會報錯 function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Person = function Person() { _classCallCheck(this, Person); };
類必須使用new調用,不然會報錯。這是它跟普通構造函數的一個主要區別,後者不用new也能夠執行。code
添加屬性和方法(包括靜態方法)對象
// es6 class Person { constructor(name, age) { this.name = name; this.age = age; } eat() { return 'eat' } static say() { return 'say' } } // 經過babel轉換成的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; } } // 檢查聲明的class類是否經過new的方式調用,不然會報錯 function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** *將方法添加到原型上,若是是靜態方法添加到構造函數上, **/ function _defineProperties(target, props) { // 遍歷函數數組,分別聲明其描述符 並添加到對應的對象上 for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; // 設置該屬性是否可以出如今對象的枚舉屬性中。默認爲 false descriptor.configurable = true; // 設置該屬性描述符可以被改變,同時該屬性也能從對應的對象上被刪除。 if ("value" in descriptor) descriptor.writable = true; // 若是屬性中存在value, value設置爲能夠改變。 Object.defineProperty(target, descriptor.key, descriptor); // 寫入對應的對象上 } } // 收集公有函數和靜態方法,將方法添加到構造函數或構造函數的原型中,並返回構造函數。 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); // 共有方法寫在property原型上 if (staticProps) _defineProperties(Constructor, staticProps); // 靜態方法寫到構造函數上 return Constructor; } var Person = function () { function Person(name, age) { _classCallCheck(this, Person); this.name = name; this.age = age; } _createClass(Person, [{ key: "eat", value: function eat() { return 'eat'; } }], [{ key: "say", value: function say() { return 'say'; } }]); return Person; }();