检查子类是否具有构造函数



这是我关于Stackoverflow的第一个问题,所以如果我做错了什么,请不要像推土机一样碾过我:(

我需要知道是否可能在JavaScript类中知道,如果孩子提供了构造函数。

例如

class Parent {
constructor() {
console.log('Child has constructor:', /* Magic here */)
}
}
class Child extends Parent {}
new Child()

预期输出:Child has constructor: false

Vs:

class Parent {
constructor() {
console.log('Child has constructor:', /* Magic here */)
}
}
class Child extends Parent {
constructor() {
super()
}
}
new Child()

预期输出:Child has constructor: true

背景:我希望类在扩展时的行为与直接使用时的行为不同。因为Childs应该向家长提供与直接使用不同的信息。

您可以向Parent构造函数添加一个默认为false的参数,然后当您在Child类内部调用super时,您可以为该参数传递true。

class Parent {
constructor(called = false) {
console.log('Child has constructor:', called)
}
}
class Child extends Parent {
constructor() {
super(true)
}
}
class ChildTwo extends Parent {}
new Child()
new ChildTwo()

不,这是不可能的。

JavaScript中的class语法只是普通function的语法暗示。

以ES6为例:

class Parent {
constructor(value){
this.example = value;
}
parentMethod(){
console.log('parent:', this.example);
}
}
class Child extends Parent {
childMethod(){
console.log('children:', this.example);
}
}
const parent = new Parent('Hello');
const child = new Child('World');
parent.parentMethod();
child.childMethod();
console.log(parent.constructor);
console.log(child.constructor);

正如您所看到的,即使您没有显式定义构造函数,类也总是有一个构造函数。

上面的内容可以大致翻译成下面的ES5代码,它还不支持class语法:

function Parent(value){
this.example = value;
}
Object.defineProperties(Parent.prototype, {
parentMethod: {
writable: true,
enumerable: false,
configurable: true,
value: function(){
console.log('parent:', this.example);
}
}
});
function Child(value){
Parent.call(this, value);
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
Child.prototype = Object.defineProperties(Child.prototype, {
childMethod: {
writable: true,
enumerable: false,
configurable: true,
value: function(){
console.log('child:', this.example);
}
}
});
var parent = new Parent('Hello');
var child = new Child('World');
parent.parentMethod();
child.childMethod();
console.log(parent.constructor);
console.log(child.constructor);

正如你所看到的:

  1. class仅仅是一个函数
  2. .constructor总是被分配的

因此,您无法检查子类是否有构造函数,因为构造函数总是在那里。

即使你能做到(但你不能做到(,父级也不会事先知道什么类会扩展它,所以它不会知道未来的子级是否会有构造函数。

我需要知道在JavaScript类中是否可能知道,如果子级提供了构造函数。

没有构造函数就没有类。有些类可能有一个隐式构造函数(class语法中没有constructor(,但您不能也不应该检测到这一点。

我希望有一个类,当它被扩展时,它的行为与直接使用时不同

您可以使用new.target == Parent区分new Childnew Parent调用。

Childs应向Parent提供与直接使用不同的信息。

这是个坏主意。你的父构造函数应该有一个不关心谁在使用它的接口

  • 永远不要直接使用父类,而是自己扩展它,并为默认用途提供该类。它可以处理不同的信息
  • 使父类接受不同类型的信息,即重载其接口。区分你得到的信息,并采取相应的行动。然而,信息是由用户直接提供还是由子类生成并不重要

最新更新