如何使用 js 实现一个 ES6 中 class 的 extends 功能 All In One
如何使用 js 实现一个 ES6 中 class 的 extends 功能 All In One
extends
class DateFormatter extends Date {
getFormattedDate() {
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
return `${this.getDate()}-${months[this.getMonth()]}-${this.getFullYear()}`;
}
}
extends
The extends keyword is used in class declarations or class expressions to create a class that is a child of another class.
extends 关键字在类声明或类表达式中用于创建一个类,该类是另一个类的子类。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends
Classes
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
- class expression
// anonymous class
const Rectangle = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
area() {
return this.height * this.width;
}
};
// named class
const Rectangle = class RectAngle {
constructor(height, width) {
this.height = height;
this.width = width;
}
area() {
return this.height * this.width;
}
};
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/class
- class declaration
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
area() {
return this.height * this.width;
}
};
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class
super
The super keyword is used to access properties on an object literal or class's [[Prototype]], or invoke a superclass's constructor.
super 关键字用于访问对象字面量或类的 [[Prototype]] 上的属性,或调用超类的构造函数
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
实现原理分析
Any constructor that can be called with new and has the prototype property can be the candidate for the parent class.
任何可以用new调用并具有prototype属性的构造函数都可以作为父类的候选。
The two conditions must both hold — for example, bound functions and Proxy can be constructed, but they don't have a prototype property, so they cannot be subclassed.
这两个条件必须同时成立——例如,可以构造绑定函数和 Proxy,但它们没有原型属性,因此它们不能被子类化。
The prototype property of the ParentClass must be an Object or null, but you would rarely worry about this in practice, because a non-object prototype doesn't behave as it should anyway. (It's ignored by the new operator.)
父类的原型属性必须是 Object 或 null,但在实践中您很少会担心这一点,因为非对象原型无论如何都不会表现得像它应该的那样。 (它被 new 运算符忽略。)
extends sets the prototype for both ChildClass and ChildClass.prototype.
extends 为 ChildClass 和 ChildClass.prototype 设置原型。

The right-hand side of extends does not have to be an identifier. You can use any expression that evaluates to a constructor. This is often useful to create mixins.
extends 的右侧不必是标识符。您可以使用任何计算结果为构造函数的表达式。这对于创建 mixins 通常很有用。
...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends
代码实现
ES6 extends
class Human {
constructor(name) {
this.name = name ?? 'unknown';
}
getName() {
return this.name;
}
setName(name) {
if(name) {
this.name = name;
}
}
}
class Person extends Human {
constructor(name) {
// super 调用父类 constructor
super(name);
this.alias = `👻${name}`;
}
}
const person = new Person('xgqfrms');

ES5 模拟 ES6
function Human(name) {
this.name = name ?? 'unknown';
}
Human.prototype.getName = function() {
return this.name;
};
Human.prototype.setName = function(name) {
if(name) {
this.name = name;
}
}
function Person(name) {
// call 调用父类 constructor ??? extends
Human.call(this, name);
this.alias = `👻${name}`;
}
// 复制父类的 prototype
Person.prototype = Object.create(Human.prototype);
// 复制自身的 constructor
Person.prototype.constructor = Person;
const person = new Person('xgqfrms');

(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!
refs
©xgqfrms 2012-2021
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/17189520.html
未经授权禁止转载,违者必究!

浙公网安备 33010602011771号