提问人:reactfreakoutovercome 提问时间:10/13/2023 最后编辑:T.J. Crowderreactfreakoutovercome 更新时间:10/14/2023 访问量:57
使用与父级相同的方法扩展类并返回对象,但构造函数不同
Extend class and return object with same methods as parents but different constructor
问:
我正在尝试从外部库扩展一个类,该库包含在开始任何操作之前在输入中使用其构造函数的方法,因为它可以有多种类型。我想创建一个工作方式与它类似但对输入进行清理的类。
class ParentClass {
constructor(value: ParentClass.ValueType) {
// ...
}
methodUsingConstructor(otherValue: ParentClass.ValueType) {
const x = new this.constructor(otherValue)
// do some stuff here with x ...
return result;
}
// ...
}
如果我这样做
class SafeParentClass extends ParentClass {
constructor(value: ParentClass.ValueType) {
// Do some input sanitizing ...
super(sanitizedValue);
}
}
我可以用.但是,我将获得一个带有 ParentClass 构造函数的对象。这意味着如果我这样做,则不会进行消毒,并且会出现错误。new SafeParentClass(value)
(new SafeParentClass(value1)).methodUsingConstructor(value2)
value2
我怎样才能创建一个我可以调用的方法,并且它们将有一个构造函数来清理输入?SafeParentClass
ParentClass
例:
import { Decimal } from 'decimal.js';
class SafeDecimal extends Decimal {
constructor(value: Decimal.Value) {
if (typeof value === 'string') {
super(parseFloat(value)); // will do super('NaN') if value is not parseable
} else {
super(value);
}
}
}
然后测试它
describe('safeDecimal', () => {
it('should return NaN output with invalid input', () => {
expect(new SafeDecimal('123123').add('').toString()).toEqual('NaN');
});
});
这会抛出一个 .DecimalError
答:
恐怕,您必须在派生类中自己实现所有方法。如果第三方类的方法的逻辑不能完全按照您的要求执行操作,则可以创建一个派生类,并将原始方法称为 。使用此技术,您可以首先清理输入,然后将其定向到原始方法。super.method(…)
基本上,这是你如何做到的:
class ThirdPartyClass {
method(argument) {
// the logic here unsafely uses the argument
}
}
class DerivedClass extends ThirdPartyClass {
override method(argument) {
const safeArgument = sanitize(argument)
return super.method(safeArgument)
}
}
您必须对正在使用的所有方法执行此操作。
评论
override
问题是写的方式。具体来说,它覆盖了每个实例上的属性(而不是允许它从原型继承,这是正常的事情)。它在 () 中的当前第 4,290 行上执行此操作。对它的评论说,它这样做是为了掩盖继承的“......这就是对象
。(正常的做法是修复继承的 insetad。decimal.js
constructor
Decimal
decimal.mjs
x.constructor = Decimal;
您可以通过覆盖以下功能来解决此问题:decimal.js
class SafeDecimal extends Decimal {
constructor(value: Decimal.Value) {
if (typeof value === "string") {
super(parseFloat(value)); // will do super('NaN') if value is not parseable
} else {
super(value);
}
this.constructor = SafeDecimal; // <=== Here
}
}
然后,使用构造函数并计算示例起作用(结果为 )。我没有测试过其他东西。NaN
在正常情况下,您不需要这个。它只是因为特定的编写方式而有必要。decimal.js
话虽如此,您可能希望分叉它并执行您认为需要在分叉中进行的更改。
最后,您可能需要考虑做一些比 更健壮的事情,因为会很乐意返回字符串(而抛出错误或返回可能更合理)。以下是您可能用来构建更强大的工具的各种选项的答案。parseFloat
parseFloat
123
"123asdlfkjasldf"
NaN
评论
新的safeParentClass(value)。
但是,我将获得一个带有ParentClass
构造函数的对象。“是什么让你这么想的?你在做一个在你的?(如果是这样:不要。return
constructor
(new safeParentClass(value1)).methodUsingConstructor(value2)
.add('')