gpt4 book ai didi

没有 OOP 类的 Javascript 多态性

转载 作者:行者123 更新时间:2023-12-05 09:15:01 25 4
gpt4 key购买 nike

在 JS 或 OOP 语言中,多态性是通过创建不同的类型来创建的。

例如:

class Field {...}

class DropdownField extends Field {
getValue() {
//implementation ....
}
}

假设我有一个带有一些方法的库 forms.js:

class Forms {
getFieldsValues() {
let values = [];
for (let f of this.fields) {
values.push(f.getValue());
}
return values;
}
}

这会获取所有字段值。请注意,库不关心它是什么字段。

通过这种方式,开发人员 A 创建了库,开发人员 B 可以创建新字段:AutocompleterField。

他可以在不更改库代码(Forms.js)的情况下在AutocompleterField中添加方法。

如果我在JS中使用函数式编程方法,我该如何实现?

如果我在对象中没有方法,我可以使用 case 语句,但这违反了原则。类似这样:

if (field.type == 'DropdownField')...
else if (field.type == 'Autocompleter')..

如果开发人员 B 添加新类型,他应该更改库代码。

那么有什么好的方法可以在不使用面向对象编程的情况下解决javascript中的问题。

我知道 Js 既不完全是 OOP 也不完全是 FP,但无论如何。

谢谢

最佳答案

JavaScript 是一种多用途语言,您当然可以用不同的方式解决它。当切换到函数式编程时,答案非常简单:使用函数!您的示例的问题在于:它是如此精简,您只需 3 行就可以完成与它完全相同的操作:

// getValue :: DOMNode -> String
const getValue = field => field.value;

// readForm :: Array DOMNode -> Array String
const readForm = formFields => formFields.map(getValue);

readForm(Array.from(document.querySelectorAll('input, textarea, select')));
// -> ['Value1', 'Value2', ... 'ValueN']

关键是:Field::getValue() 是如何实现的,它返回 什么?或者更准确地说:DropdownField::getValue()AutocompleteField::getValue() 有何不同,例如 NumberField::getValue() ?他们都只返回值(value)吗?他们返回一对名称和值吗?他们甚至需要与众不同吗?

问题是,您的 Field 类和它们的继承类是因为它们的 getValue() 方法的工作方式不同,还是因为其他功能而不同他们有?例如,文本字段的“自动完成”功能不(或不应)与从中获取值的方式相关联。

如果你真的需要以不同的方式读取值,你可以实现一个函数,它接受 {fieldtype: readerFunction} 对的 map/dictionary/object/POJO:

/* Library code */

// getTextInputValue :: DOMNode -> String
const getTextInputValue = field => field.value;

// getDropdownValue :: DOMNode -> String
const getDropdownValue = field => field.options[field.selectedIndex].value;

// getTextareaValue :: DOMNode -> String
const getTextareaValue = field => field.textContent;

// readFieldsBy :: {String :: (a -> String)} -> DOMNode -> Array String
readFieldsBy = kv => form => Object.keys(kv).reduce((acc, k) => {
return acc.concat(Array.from(form.querySelectorAll(k)).map(kv[k]));
}, []);



/* Code the library consumer writes */

const readMyForm = readFieldsBy({
'input[type="text"]': getTextInputValue,
'select': getDropdownValue,
'textarea': getTextareaValue
});

readMyForm(document.querySelector('#myform'));
// -> ['Value1', 'Value2', ... 'ValueN']

注意:我有意没有在这里提到诸如 IO monad 之类的东西,因为它会使事情变得更复杂,但你可能想要查找它。

关于没有 OOP 类的 Javascript 多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53276744/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com