在不使用超级构造函数的情况下,如何让 ES6 Class 方法在调用子类函数时执行一些默认行为?
How could I make a ES6 Class method execute some some default behaviour when a subclass function is called, without using the super constructor?
所以尝试构建一些 js classes 我 运行 遇到了一些知识空白,因为这是我第一次实现 OOP 和 ES6 构造函数。
我基本上有一个 运行 是一个 respond()
方法的应用程序,当在 "Emergency Event"
执行时,我需要从其父 class 执行一些默认行为].
在这个例子中,所有从 NuclearStrategy
派生的子class 应该总是 Appease the population
无论在 Action
子class respondToThreat()
方法为例。如果 eventIsJustTest === true
那么除了 Appease the population
.
什么都不应该做
这就是我正在实施的:
class NuclearStrategy {
constructor(props) {
this.eventOrigin = props.eventOrigin;
}
appeaseAllPopulation() {
console.log('✅ Appeasing the population');
}
respondToThreat({ eventIsJustTest }) {
this.appeaseAllPopulation();
if (eventIsJustTest) return; // I expect this to exit the function and ignore anything declared after <super.respondToThreat()>
}
}
class Action extends NuclearStrategy {
constructor(props) {
super(props)
}
respondToThreat(responseArgs) {
super.respondToThreat(responseArgs.eventIsJustTest); // <- I can't have this in my code
console.log(`✅ Playing alert siren`); // <- This shouldn't be executed
console.log(`✅ Launched ICBM nuke to enemy`) // <- Avoid also
}
}
new Action({ eventOrigin: 'East Qorea' }).respondToThreat({ eventIsJustTest: true });
这执行
✅ Appeasing the population
✅ Playing alert siren
✅ Launched ICBM nuke to enemy
应该只执行
✅ Appeasing the population
有了这个,即使警报只是针对 nuclear test
(RIP Earth),我也无法阻止使用 Action.respondToThreat
发射的核弹。另外,我的子 class super.respondToThreat()
不能有任何 super
调用,默认情况下应该执行 appeaseAllPopulation()
行为 没有调用它.
您对这个申请有什么建议吗?
提前谢谢你。
一个简单的解决方案是根本不覆盖 respondToThreat
,而是调用应由子 类.
实现的 method/hook
class NuclearStrategy {
constructor(props) {
this.eventOrigin = props.eventOrigin;
}
appeaseAllPopulation() {
console.log('Broadcasting ');
}
respondToThreat({ eventIsJustTest }) {
console.log(`✅ Appeasing the population`);
if (eventIsJustTest) return;
this.respondToNonTestThreat();
}
respondToNonTestThreat() {} // default implementation do nothing
}
class Action extends NuclearStrategy {
respondToNonTestThreat() {
console.log(`✅ Playing alert siren`);
console.log(`✅ Launched ICBM nuke to enemy`);
}
}
const action = new Action({ eventOrigin: 'East Qorea' });
console.log("test threat:");
action.respondToThreat({ eventIsJustTest: true });
console.log("non-test threat:");
action.respondToThreat({});
如果你想防止程序员覆盖重要的方法,而不是 sub-classing 你可以只传递要执行的逻辑。在这种情况下,调用逻辑的 class 应该记录在什么情况下执行什么逻辑。传递的参数是什么以及预期的 return 值应该是什么。
以上可以通过多种不同的方式完成,这里是一个例子:
class Hooks {
constructor(hooks, context) {
this.hooks = hooks;
this.context = context;
}
find(...path) {
let cursor = this.hooks;
for (const key of path) {
if (!cursor[key]) return this.noop;
cursor = cursor[key];
}
return cursor.bind(this.context);
}
noop() {}
}
class NuclearStrategy {
static withPresetHooks(hooks) {
return (props) => new this({ ...props, hooks });
}
constructor(props) {
this.eventOrigin = props.eventOrigin;
this.hooks = new Hooks(props.hooks || {}, this);
}
appeaseAllPopulation() {
console.log('Broadcasting ');
}
respondToThreat({ eventIsJustTest }) {
console.log(`✅ Appeasing the population`);
this.hooks.find("respondToThreat", "eventIsJustTest", !!eventIsJustTest)();
}
}
const createAction = NuclearStrategy.withPresetHooks({
respondToThreat: {
eventIsJustTest: {
true: function () {
console.log(`✅ Testing alert siren`);
},
false: function () {
console.log(`✅ Playing alert siren`);
console.log(`✅ Launched ICBM nuke to enemy`);
},
},
},
});
const action = createAction({ eventOrigin: 'East Qorea' });
console.log("test threat:");
action.respondToThreat({ eventIsJustTest: true });
console.log("non-test threat:");
action.respondToThreat({});
所以尝试构建一些 js classes 我 运行 遇到了一些知识空白,因为这是我第一次实现 OOP 和 ES6 构造函数。
我基本上有一个 运行 是一个 respond()
方法的应用程序,当在 "Emergency Event"
执行时,我需要从其父 class 执行一些默认行为].
在这个例子中,所有从 NuclearStrategy
派生的子class 应该总是 Appease the population
无论在 Action
子class respondToThreat()
方法为例。如果 eventIsJustTest === true
那么除了 Appease the population
.
这就是我正在实施的:
class NuclearStrategy {
constructor(props) {
this.eventOrigin = props.eventOrigin;
}
appeaseAllPopulation() {
console.log('✅ Appeasing the population');
}
respondToThreat({ eventIsJustTest }) {
this.appeaseAllPopulation();
if (eventIsJustTest) return; // I expect this to exit the function and ignore anything declared after <super.respondToThreat()>
}
}
class Action extends NuclearStrategy {
constructor(props) {
super(props)
}
respondToThreat(responseArgs) {
super.respondToThreat(responseArgs.eventIsJustTest); // <- I can't have this in my code
console.log(`✅ Playing alert siren`); // <- This shouldn't be executed
console.log(`✅ Launched ICBM nuke to enemy`) // <- Avoid also
}
}
new Action({ eventOrigin: 'East Qorea' }).respondToThreat({ eventIsJustTest: true });
这执行
✅ Appeasing the population
✅ Playing alert siren
✅ Launched ICBM nuke to enemy
应该只执行
✅ Appeasing the population
有了这个,即使警报只是针对 nuclear test
(RIP Earth),我也无法阻止使用 Action.respondToThreat
发射的核弹。另外,我的子 class super.respondToThreat()
不能有任何 super
调用,默认情况下应该执行 appeaseAllPopulation()
行为 没有调用它.
您对这个申请有什么建议吗? 提前谢谢你。
一个简单的解决方案是根本不覆盖 respondToThreat
,而是调用应由子 类.
class NuclearStrategy {
constructor(props) {
this.eventOrigin = props.eventOrigin;
}
appeaseAllPopulation() {
console.log('Broadcasting ');
}
respondToThreat({ eventIsJustTest }) {
console.log(`✅ Appeasing the population`);
if (eventIsJustTest) return;
this.respondToNonTestThreat();
}
respondToNonTestThreat() {} // default implementation do nothing
}
class Action extends NuclearStrategy {
respondToNonTestThreat() {
console.log(`✅ Playing alert siren`);
console.log(`✅ Launched ICBM nuke to enemy`);
}
}
const action = new Action({ eventOrigin: 'East Qorea' });
console.log("test threat:");
action.respondToThreat({ eventIsJustTest: true });
console.log("non-test threat:");
action.respondToThreat({});
如果你想防止程序员覆盖重要的方法,而不是 sub-classing 你可以只传递要执行的逻辑。在这种情况下,调用逻辑的 class 应该记录在什么情况下执行什么逻辑。传递的参数是什么以及预期的 return 值应该是什么。
以上可以通过多种不同的方式完成,这里是一个例子:
class Hooks {
constructor(hooks, context) {
this.hooks = hooks;
this.context = context;
}
find(...path) {
let cursor = this.hooks;
for (const key of path) {
if (!cursor[key]) return this.noop;
cursor = cursor[key];
}
return cursor.bind(this.context);
}
noop() {}
}
class NuclearStrategy {
static withPresetHooks(hooks) {
return (props) => new this({ ...props, hooks });
}
constructor(props) {
this.eventOrigin = props.eventOrigin;
this.hooks = new Hooks(props.hooks || {}, this);
}
appeaseAllPopulation() {
console.log('Broadcasting ');
}
respondToThreat({ eventIsJustTest }) {
console.log(`✅ Appeasing the population`);
this.hooks.find("respondToThreat", "eventIsJustTest", !!eventIsJustTest)();
}
}
const createAction = NuclearStrategy.withPresetHooks({
respondToThreat: {
eventIsJustTest: {
true: function () {
console.log(`✅ Testing alert siren`);
},
false: function () {
console.log(`✅ Playing alert siren`);
console.log(`✅ Launched ICBM nuke to enemy`);
},
},
},
});
const action = createAction({ eventOrigin: 'East Qorea' });
console.log("test threat:");
action.respondToThreat({ eventIsJustTest: true });
console.log("non-test threat:");
action.respondToThreat({});