一、class的基本实现
JavaScript 语言中,生成实例对象的传统方法是通过构造函数。下面是一个例子。
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
上面这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大,很容易让新学习这门语言的程序员感到困惑。
ES6中新引入了类的概念,作为对象的模板。通过 class 关键字,可以定义类 。
基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法让对象原型的写法更加清晰、更像面向对象编程的语法。
上面得代码,使用es6得类来写,写法如下:
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
既然是语法糖,那我们来看下,这个糖是怎么实现得。
接下来讲上面的 es6 的类写法放到一个 babel 转码器中,看从es6 转化为 es5 的过程,到底是什么样的。
以下是转码后的结果:
'use strict';
var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Point = function () {
// 定义构造函数
function Point(x, y) {
_classCallCheck(this, Point);
this.x = x;
this.y = y;
}
// 创建类
_createClass(Point, [{
key: 'toString',
value: function toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}]);
return Point;
}();
_classCallCheck()方法
function _classCallCheck(instance, Constructor) {
if (! (instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
_createClass () 方法
var _createClass = function() {
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);
}
}
return function(Constructor, protoProps, staticProps) {
// 原型属性
if (protoProps) defineProperties(Constructor.prototype, protoProps);
// 静态属性
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
} ();