原文:Classes in JavaScript
从ES6/2015开始,JavaScript新增了面向对象编程的内置关键字class
。本文介绍了它的工作原理。
在面向对象编程中,类 是创建对象的模板。JavaScript的class
关键字 可以声明一个新的类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Rectangle { constructor (height, width ) { this .height = height; this .width = width; } } const obj = new Rectangle (3 , 5 );obj.height ; obj.width ; obj instanceof Rectangle ; ({}) instanceof Rectangle ;
方法 方法 就是定义在类中的函数,JavaScript会将方法添加到每个类的实例中。例如,要计算Rectangle
的面积,可以定义一个area()
方法,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Rectangle { constructor (height, width ) { this .height = height; this .width = width; } area ( ) { return this .width * this .height ; } } const obj = new Rectangle (3 , 5 );obj.area ();
在这个方法中,this
关键字 指向了方法所属的类的实例。以上代码中的this
指向obj
。
Statics A static is a a function that is defined on the class itself. In JavaScript, a class is just another variable, so you can call static functions on a class.
Static static
关键字代表函数是定义到类本身的。JavaScript中,一个类也是一个变量,可以直接调用类的静态函数 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Rectangle { constructor (height, width ) { this .height = height; this .width = width; } static createSquare (length ) { return new Rectangle (length, length); } } const obj = Rectangle .createSquare (5 );obj.height ; obj.width ;
getter/setter 定义Rectangle
的area
,可以用另一种方法——getter
。使用getter
,不使用方法,就能创建一个动态计算的Rectangle
的area
属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Rectangle { constructor (height, width ) { this .height = height; this .width = width; } get area () { return this .height * this .width ; } } const obj = new Rectangle (3 , 5 );obj.area ;
同样,也可以定义一个setter
,在设置某个属性时进行调用。例如,需要确定height
和width
都是数值型,可以定义setter
,在设置为非数值型时抛出异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Rectangle { constructor (height, width ) { this .height = height; this .width = width; } get height () { return this ._height ; } set height (v ) { assert.ok (typeof v === 'number' , 'height必须为数值型' ); return v; } get width () { return this ._width ; } set width (v ) { assert.ok (typeof v === 'number' , 'width必须为数值型' ); return v; } } const obj = new Rectangle (3 , 5 );obj.height = 'Not a number' ;
继承 当一个类继承另一个类 ,意味着子类默认具有所有父类的静态方法、方法、getter
和setter
。而子类可以定义额外的静态方法、方法、getter
和setter
,子类还可以覆盖 基类的静态方法、方法、getter
和setter
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Rectangle { constructor (height, width ) { this .height = height; this .width = width; } area ( ) { return this .width * this .height ; } } class Square extends Rectangle { constructor (length ) { super (length, length); } inradius ( ) { return this .height / 2 ; } } const obj = new Square (5 );obj.area (); obj.inradius (); obj instanceof Square ; obj instanceof Rectangle ;
继承仍然是基于原型的 关键字extends
在底层仍然使用基于原型的继承 。也就是说,可以在ES6的类中,混合使用原型模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Rectangle { constructor (height, width ) { this .height = height; this .width = width; } } Rectangle .prototype .area = function area ( ) { return this .width * this .height ; }; const obj = new Rectangle (3 , 5 );obj.area ();