本文共 3294 字,大约阅读时间需要 10 分钟。
响应式设计已经成为现代前端开发的核心原则,而类继承机制则为这个原则提供了强大支持。在ES6中,class语法为我们提供了构造函数的语法糖,使继承操作变得更加简便。而用extends关键字实现的原型链继承,使得面后台开发中的代码复用和代码维护更加高效。
class User {}class Son extends User {} 经过以上代码,Son类不仅可以使用User类的所有属性和方法,还可以基于User的构造函数新建实例。例如:
class User { constructor(a) { this.a = a; this.b = 10; } eat() { console.log('user eat'); }}class Son extends User { constructor(b, c) { super(b); this.c = c; } sum() { console.log(this.a, this.b, this.c); }}var son = new Son(1, 2);son.eat(); // user eatson.sum(); // 1 10 2 作为函数时,super在子类构造函数中必须被调用。如果子类没有定义构造函数,JavaScript会为其默认生成一个构造函数。需要注意的是,只有在调用super之后,才可以放心地使用this关键字。在静态方法中,super会指向父类。
class User { constructor() { this.a = 1; this.b = 1; } eat() { console.log(this.b); // 10 return 2; }}class Son extends User { constructor() { super(); this.b = 10; console.log(super.c); // undefined console.log(this.c); // 20 } talk() { console.log(super.a); // undefined console.log(super.eat()); // 2 }}var son = new Son();son.talk(); 使用Object.getPrototypeOf可以获取子类的原型链。对于类来说,均具备__proto__和prototype属性。
class User {}class Son extends User { // ...}console.log(Object.getPrototypeOf(Son) === User); // true 通过查看__proto__属性,可以了解类的继承关系。同时,子类实例的__proto__属性也指向父类实例的__proto__。
class User {}class Son extends User {}console.log(Son.__proto__ === User.__proto__); // falseconsole.log(Son.__proto__.__proto__ === User.__proto__; // true 在ES6之前,原生的数据类型如Array无法通过继承方式扩展。然而,ES6允许我们自定义原生数据结构的子类。
class MyArray extends Array { constructor(...args) { super(...args); }}var arr = new MyArray(); Mixin模式允许我们将多个对象合并为一个。在阮大神的实现中,Mixin不仅能复用静态属性和方法,还能实现属性的深拷贝。
function mix(...mixins) { class Mix { constructor() { for (let mixin of mixins) { copyProperties(this, new mixin()); } } } for (let mixin of mixins) { copyProperties(Mix, mixin); copyProperties(Mix.prototype, mixin.prototype); } return Mix;}function copyProperties(target, source) { for (let key of Reflect.ownKeys(source)) { if (key !== 'constructor' && key !== 'prototype' && key !== 'name') { let desc = Object.getOwnPropertyDescriptor(source, key); Object.defineProperty(target, key, desc); } }}class DistributedEdit extends mix(Loggable, Serializable) { // 具体实现在此省略} 对于静态方法,super指向的是父类本身,而不是父类的原型链。以下代码展示了静态方法如何正确继承:
class User { constructor() { this.a = 10; } static eat(val) { console.log('static', val); } eat(val) { console.log('instance', val); } static talk() { console.log(this.a); }}class Son extends User { constructor() { super(); this.a = 20; } static eat(val) { super.eat(val); } eat(val) { super.eat(val); } static talk() { super.talk(); }}Son.a = 30;Son.talk(); // 30Son.eat(1); // static 1var son = new Son();son.eat(2); // instance 2 通过以上内容,我们可以清晰地看到,ES6类继承机制为前端开发带来了更加灵活和高效的工具。理解并正确运用这些概念,是提升开发效率的关键所在。
转载地址:http://jennz.baihongyu.com/