一、class的定义
作为对象的模板。可以看作是一个语法糖。相当于实例的原型
-- constructor代表构造方法,this关键字代表实例对象。
-- 定义类的时候,前面不需要加上function这个关键字。
-- 方法间不需要加,分割
-- 类的数据类类型就是函数,类本身指向构造函数
-- 类的所有方法都定义在类的prototype属性上面
--与函数一样,Class也可以使用表达式的形式定义,需要注意的是 Point只在Class内部有定义。
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return ‘(‘ + this.x + "," + this.y + ")"; } toValue() { return this.x + this.y; } }
二、类的私有方法和私有属性
1、私有方法
-- _print方法前面的下划线,表示这是一个只限于内部使用的私有方法。
-- Symbol
值的唯一性,将私有方法的名字命名为一个Symbol
值。
const bar = Symbol(‘bar‘); const snaf = Symbol(‘snaf‘); export default class myClass{ // 公有方法 foo(baz) { this[bar](baz); } // 私有方法 [bar](baz) { return this[snaf] = baz; } // ... };
2、私有属性
与私有方法一样,ES6 不支持私有属性。目前,有一个提案,为class
加了私有属性。方法是在属性名之前,使用#
表示。
class Point { #x; constructor(x = 0) { #x = +x; // 写成 this.#x 亦可 } get x() { return #x } set x(value) { #x = +value }}}
三、Class的静态方法和静态属性
1、类的静态方法:类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static
关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
class Foo { static classMethod() { return ‘hello‘; }} Foo.classMethod() // ‘hello‘ var foo = new Foo(); foo.classMethod() // TypeError: foo.classMethod is not a function
注意:
-- 父类的静态方法,可以被子类继承。
class Foo { static classMethod() { return ‘hello‘; }} class Bar extends Foo {} Bar.classMethod() // ‘hello‘
-- 静态方法也是可以从super
对象上调用的。
class Foo { static classMethod() { return ‘hello‘; }} class Bar extends Foo { static classMethod() { return super.classMethod() + ‘, too‘; }} Bar.classMethod() // "hello, too"
2、类的静态属性和实例属性
静态属性: Class 本身的属性,即Class.propName。
实例属性: 出了构造器中的this.x= x;还可以
新提案
实例属性: 用等式,写入类的定义之中
class MyClass { myProp = 42; constructor() { console.log(this.myProp); // 42 }}
静态属性: 只要在上面的实例属性写法前面,加上static
关键字就可以了
class MyClass { static myStaticProp = 42; constructor() { console.log(MyClass.myStaticProp); // 42 }}
四、this指向
类的方法内部如果含有this
,它默认指向类的实例。但是,必须非常小心,一旦单独使用该方法,很可能报错。
class Logger { printName(name = ‘there‘) { this.print(`Hello ${name}`); } print(text) { console.log(text); }} const logger = new Logger(); const { printName } = logger;printName(); // TypeError: Cannot read property ‘print‘ of undefined
解决:
-- 一个比较简单的解决方法是,在构造方法中绑定this
,这样就不会找不到print
方法了。
class Logger { constructor() { this.printName = this.printName.bind(this); } // ... }
-- 使用箭头函数
class Logger { constructor() { this.printName = (name = ‘there‘) => { this.print(`Hello ${name}`); }; } // ... }