ES6 之 Class 的基本语法和继承

Class 类基本用法
class Person {constructor(name,age) {this.name = name;this.age = age;}getName(){console.log(`My name is ${this.name}!`)}static sayHi() {console.log('Hi');}}let p = new Person();typeof Person // "function"p instanceof Person // true
constructor 方法
class Person {}Person.prototype // {construtor:f}
class Foo {constructor(){return Object.create(null);}}new Foo() instanceof Foo // false
class Foo {constructor(){}}Foo() // TypeError: Class constructor Foo cannot be invoked without 'new'
Class 的自定义方法
class Person {constructor() {}aaa(){}bbb(){}}Object.getOwnPropertyNames(Person.prototype) // ["constructor", "aaa", "bbb"]
Person.prototype.constructor === Person // truep.constructor === Person // true
Object.assign 向 prototype 一次性添加多个。class Person {constructor() {}}Object.assign(Person.prototype, {aaa(){},bbb(){}})
function 关键字,也不需要逗号分隔。Class 内部所有定义的方法,都是不可枚举的。class Person {constructor() {}aaa(){}}Object.keys(Person.prototype) // []Object.getOwnPropertyNames(Person.prototype) // ["constructor", "aaa"]
prototype 原型定义的方法是可枚举的。let Person = function(){};Person.prototype.aaa = function(){};Object.keys(Person.prototype) // ["aaa"]Object.getOwnPropertyNames(Person.prototype) // ["constructor", "aaa"]
let methodName = 'getName';class Person {constructor() {}[methodName](){}}Object.getOwnPropertyNames(Person.prototype) // ["constructor", "getName"]
取值函数 getter 和存值函数 setter
class Person {constructor() {this.name = 'dora';}get author() {return this.name;}set author(value) {this.name = this.name + value;console.log(this.name);}}let p = new Person();p.author // dorap.author = 666; // dora666
Object.getOwnPropertyNames(Person.prototype) // ["constructor", "author"]Object.getOwnPropertyDescriptor(Person.prototype,'author')// { get: ƒ author()(),// set: ƒ author()(value),// ...// }
Class 的 static 静态方法
class Person {static sayHi() {console.log('Hi');}}Person.sayHi() // "Hi"let p = new Person();p.sayHi() // TypeError: p.sayHi is not a function
this 关键字,这个 this 指的是类,而不是实例。静态方法可以与非静态方法重名。class Person {static sayHi() {this.hi();}static hi(){console.log('hello')}hi(){console.log('world')}}Person.sayHi() // "hello"
实例属性的另一种写法
class Person {name = 'dora';getName() {return this.name;}}let p = new Person();p.name // "dora"Object.keys(p) // ["name"]
Class 的继承
class Person {constructor() {}sayHi() {return 'Hi';}}class Teacher extends Person {constructor() {super();}}let t = new Teacher();t.sayHi(); // "Hi"
子类的 constructor
class Teacher extends Person {}let t = new Teacher();t.sayHi(); // "Hi"
class Teacher extends Person {constructor(...args) {super(...args);}}
super 关键字
super() 方法
class A {constructor() {console.log(this.constructor.name)}}class B extends A {constructor() {super();}}new A() // Anew B() // B
super 对象
class A {constructor() {this.a = 3;}p() {return 2;}}A.prototype.m = 6;class B extends A {constructor() {super();console.log(super.a); // undefinedconsole.log(super.p()); // 2console.log(super.m); // 6}}new B();
super 调用父类方法时,方法内部的 this 指向当前的子类实例。class A {constructor() {this.x = 'a';}aX() {console.log(this.x);}}class B extends A {constructor() {super();this.x = 'b';}bX() {super.aX();}}(new B()).bX() // 'b'
class A {static m(msg) {console.log('static', msg);}m(msg) {console.log('instance', msg);}}class B extends A {static m(msg) {super.m(msg);}m(msg) {super.m(msg);}}B.m(1); // "static" 1(new B()).m(2) // "instance" 2
任意对象的 super
let obj = {m() {return super.constructor.name;}};obj.m(); // Object
class B extends A {m() {console.log(super);}}// SyntaxError: 'super' keyword unexpected here
静态方法的继承
class Person {static sayHi() {return 'hello';}}class Teacher extends Person {}Teacher.sayHi() // "hello"
class Teacher extends Person {static sayHi() {super.sayHi();}}Teacher.sayHi() // "hello"
new.target 属性
class Shape {constructor() {if(new.target === Shape) {throw new Error('本类不能实例化');}}}class Circle extends Shape {constructor(radius) {super();console.log('ok');}}let s = new Shape(); // 报错let cir = new Circle(6); // 'ok'
本文完〜
评论

