ES6引入了Class(类)这个概念,做为对象的模板,经过class关键字,能够定义类。基本上,ES6的class能够看做只是一个语法糖,它的绝大部分功能,ES5均可以作到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。编程
那么如何掌握类这项技能,让我来陪你们一块儿学习:app
1.super关键字函数
super用在调用的时候有两种状况:
第一种状况,super做为函数调用时,表明父类的构造函数。
第二种状况,super做为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。工具
class Person { constructor (name) { this.name = name; } height(){ console.log(1); } static weight(){ console.log(2); } } class Student extends Person { constructor (name, age) { super(); //表明父类的构造函数 this.age = age; } height(){ super.height(); //指向父类的原型对象 } static weight(){ super.weight(); //指向父类 } }
若是子类调用constructor,那么子类必须在constructor方法中调用super方法,不然新建实例时会报错。这是由于子类没有本身的this对象,而是继承父类的this对象,而后对其进行加工。若是不调用super方法,子类就得不到this对象。学习
总结下:ui
super 关键字用于调用一个对象的父对象上的函数。
super.prop 和 super[expr] 表达式在类 和 对象字面量 任何 方法定义 中都是有效的。
在构造函数中使用时,super关键字单独出现,必须在能够使用this关键字以前使用。此关键字也可用于调用父对象上的函数。this
2.static关键字spa
类至关于实例的原型, 全部在类中定义的方法, 都会被实例继承。 若是在一个方法前, 加上static关键字, 就表示该方法不会被实例继承, 而是直接经过类来调用, 这就称为“ 静态方法”。prototype
静态方法调用直接在类上进行,而在类的实例上不可被调用。code
静态方法一般用于建立 实用/工具 函数。
经过例子咱们能够发现,静态方法是经过类名直接调用的
从另外一个静态方法为了在同一个类的另外一个静态方法中调用一个静态方法,你能够使用 this 关键字。
class StaticMethodCall { static staticMethod() { return 'Static method has been called'; } static anotherStaticMethod() { return this.staticMethod() + ' from another static method'; } } StaticMethodCall.staticMethod(); // 'Static method has been called' StaticMethodCall.anotherStaticMethod(); // 'Static method has been called from another static method'
从类的构造函数和其余方法静态方法不能直接在非静态方法中使用 this 关键字来访问。你须要使用类名来调用它们:CLASSNAME.STATIC_METHOD_NAME() 或者将其做为构造函数的属性来调用该方法: this.constructor.STATIC_METHOD_NAME().
class StaticMethodCall { constructor() { console.log(StaticMethodCall.staticMethod()); // 'static method has been called.' console.log(this.constructor.staticMethod()); // 'static method has been called.' } static staticMethod() { return 'static method has been called.'; } }
3.new.target 关键字
new.target属性容许你检测函数或构造方法是否经过是经过new运算符被调用的。在经过new运算符被初始化的函数或构造方法中,new.target返回一个指向构造方法或函数的引用。在普通的函数调用中,new.target 的值是undefined。
怎么理解这段话,也就是说new.target的功能就是用来检测函数的调用是否是经过 new 去建立一个新对象的,并且new.target返回的是一个指向函数的引用,也就是说咱们可以肯定是哪一个函数进行了new操做
class A { constructor() { console.log(new.target.name); } } class B extends A { constructor() { super(); } } var a = new A(); // logs "A" var b = new B(); // logs "B"
new.target 最大的做用就是让构造器知道当前到底 new 的是哪一个类。
延伸下。ES6以前怎么实现这个功能?
var A = function A() { if(!(this instanceof A)) throw 'Constructor A requires "new"'; // ··· };
然而这依然能够经过 call 或 apply 来调用。好比:
var a = A.call(Object.create(A.prototype));
那么用ES6就是下面这样操做了
var A = function A() { if(!new.target) throw 'Constructor A requires "new"'; // ··· };
4.constructor关键字
构造方法是建立和初始化使用类建立的一个对象的一种特殊方法。
class Square extends Polygon { constructor(length) { // 在这里调用父类的"length",赋值给矩形的"width"和"height"。 super(length, length); // 注意:子类必须在constructor方法中调用super方法,不然新建实例时会报错。 this.name = 'Square'; } get area() { return this.height * this.width; } set area(value) { this.area = value; } }
若是没有显式定义,会默认添加一个空的constructor方法。对于基类"Base classes",默认构造方法以下:
constructor() {}
对于派生类"Derived classes" ,默认构造方法以下:
constructor(...args) {
super(...args);
}