ES6中class是基于原型的继承的语法糖,提供更加清晰的语法来建立对象和原型。
es5 声明一个构造函数:javascript
function Student(name, age) { this.name = name; this.age = age; } Student.prototype.getInfo = function() { return '{name:' + this.name + ',age:' + this.age + '}'; } Student.prototype.setInfo = function(name, age) { this.name = name; this.age = age; } var p = new Student('nico', 1); p.getInfo(); //{name:nico,age:1} p.setInfo('siip', 10); p.getInfo(); //{name:siip,10}
es6 声明一个类:java
class Student { constructor(name, age) { this.name = name; this.age = age; } getInfo() { return `{name:${this.name},age:${this.age}}`; } setInfo(name, age) { this.name = name; this.age = age; } } let p = new Student('nico', 1); p.setInfo('siip', 10); p.getInfo();//{name:siip,10}
以上二者相比之下,很能够看出,es6类函数比es5构造函数,代码量更少,而且结构层次更加简洁明了。es6
有些地方须要注意的是:express
constructorbabel
constructor是默认的方法,就算在声明类函数时没有写constructor方法,在实例化时会自动添加上一个空的constructor函数
class Student { constructor() { this.desc = 'test'; } }
经过babel转码:this
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Student = function Student() { _classCallCheck(this, Student);//类不能直接被调用,只能经过new实例化 this.desc = 'test'; };
constructor方法指向自身,在一个类中只能有一个名为 “constructor” 的特殊方法。es5
Student === Student.prototype.constructor;//true
staticprototype
简述:顾名思义这是一个静态方法,就是不须要实例化类就能够调用的方法, 实例化对象不能继承静态方法。code
class Student { constructor(name, age) { this.name = name; this.age = age; } static ageFilter(...args) { let stuAge = args; let arr = []; for (let i = 0; i < stuAge.length; i++) { if (stuAge[i].age > 12) { arr.push(stuAge[i]) } } return arr; } getInfo() { return `{name:${this.name},age:${this.age}}`; } setInfo(name, age) { this.name = name; this.age = age; } } Student.ageFilter({ name: 'a', age: 1 }, { name: 'b', age: 14 });//{name: "a", age: 14}
静态函数的this指向类函数自身,当this没有指明被谁调用时,this为undefined
咱们将上面代码用babel编译,从结果上看:
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; }; }();
从代码能够看出,静态方法与类函数方法的区别是:当用Object.defineProperty去定义对象属性时传入的对象不一样,一个传入的是构造函数的原型,另外一个是传入构造函数。
es6当前还不支持静态属性
extends
关键字在类声明或类表达式中用于建立一个类做为另外一个类的一个子类
class Student { constructor(name = null, age = null) { this.name = name; this.age = age; } getInfo() { return `{name:${this.name},age:${this.age}}`; } setInfo(name, age) { this.name = name; this.age = age; } } class Citizen extends Student { constructor(name, age) { super(name, age); this.name = 123; } } let stu = new Citizen('siip', '25'); stu.getInfo(); //{name:siip,age:25}
能够看到子类能够调用父类上的方法和属性,当使用extends继承父类时,子类constructor和super和被默认添加上,而且在构造函数内,只有调用了super函数后才能使用this,不然会抛出ReferenceError错误
constructor() { this.name = 'xxx' super() }//ReferenceError
super
下面一个子类继承父类的Math的方法:
function MathFns() { this.status = 'Father' } MathFns.prototype = Math; class Max extends MathFns { constructor() { super(); } static base() { return super.max(); } } let m = new MathFns(); m; //{status: "Father"} m.max(1, 2);//2
咱们能够经过babel编译,尝试去理解es6的继承,
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; }
这个封装继承函数,主要实现的功能是,子类原型指向父类,原型构造器指向自身,而后再经过隐式原型链指向父类函数,这样子类被实例化后的对像就能使用父类原型链上的方法以及经过隐式原型链访问到父类的属性。
总的来看,es6的class类其实是基于原型链和继承作的一层封装,它的结构层次相对于es5原型链写法更加清晰明了,代码量更少。class类主要内容是构造函数、静态方法、继承。
构造函数
静态方法
继承