这是我关于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);
正如你所看到的:
class
仅仅是一个函数.constructor
总是被分配的
因此,您无法检查子类是否有构造函数,因为构造函数总是在那里。
即使你能做到(但你不能做到(,父级也不会事先知道什么类会扩展它,所以它不会知道未来的子级是否会有构造函数。
我需要知道在JavaScript类中是否可能知道,如果子级提供了构造函数。
没有构造函数就没有类。有些类可能有一个隐式构造函数(class
语法中没有constructor
(,但您不能也不应该检测到这一点。
我希望有一个类,当它被扩展时,它的行为与直接使用时不同
您可以使用new.target == Parent
区分new Child
和new Parent
调用。
Childs应向Parent提供与直接使用不同的信息。
这是个坏主意。你的父构造函数应该有一个不关心谁在使用它的接口
- 永远不要直接使用父类,而是自己扩展它,并为默认用途提供该类。它可以处理不同的信息
- 使父类接受不同类型的信息,即重载其接口。区分你得到的信息,并采取相应的行动。然而,信息是由用户直接提供还是由子类生成并不重要