Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >不带OOP类的Javascript多态性

不带OOP类的Javascript多态性
EN

Stack Overflow用户
提问于 2018-11-13 08:27:45
回答 4查看 1.2K关注 0票数 2

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

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Field {...}

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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语句,但这违反了原则。如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (field.type == 'DropdownField')...
else if (field.type == 'Autocompleter')..

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

那么,在javascript中有没有什么好方法来解决这个问题,而不是使用面向对象的编程。

我知道Js既不是OOP也不是FP,但不管怎样。

谢谢

EN

回答 4

Stack Overflow用户

发布于 2018-11-13 09:44:38

JavaScript是一种多用途的语言,你当然可以用不同的方法来解决它。当切换到函数式编程时,答案非常简单:使用函数!你的例子的问题是:它是如此的精简,你可以用3行代码做同样的事情:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 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()有什么不同?它们都只是返回值吗?它们是否返回一对名称和值?他们甚至需要有所不同吗?

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

如果您确实需要以不同的方式读取值,您可以实现一个函数,该函数接受{fieldtype: readerFunction}对的映射/字典/对象/POJO:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* 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这样的东西,因为它会使事情变得更加复杂,但您可能想要查看它。

票数 5
EN

Stack Overflow用户

发布于 2018-11-13 09:22:23

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

是。或者更确切地说,通过在不同的对象中实现相同的类型接口。

没有OOP类,我如何使用Javascript多态性

你似乎在这里confuse classes with types。创建对象根本不需要JS class语法。

你可以只拥有

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const autocompleteField = {
    getValue() {}
};
const dropdownField = {
    getValue() {}
};

并在您的Forms实例中使用这两个。

票数 2
EN

Stack Overflow用户

发布于 2018-11-13 09:42:11

取决于你所说的“多态性”是什么意思。Haskell、Scala或PureScript中的类型类提供了所谓的即席多态--这种分派通常是通过将见证对象作为额外的函数参数传递来实现的,然后这些对象将知道如何执行多态功能。

例如,下面的PureScript代码(来自docs)为某些类型提供了show函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Show a where
  show :: a -> String

instance showString :: Show String where
  show s = s

instance showBoolean :: Show Boolean where
  show true = "true"
  show false = "false"

instance showArray :: (Show a) => Show (Array a) where
  show xs = "[" <> joinWith ", " (map show xs) <> "]"

example = show [true, false]

它被编译成下面的JS (我把它缩短了):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var Show = function (show) {
    this.show = show;
};

var show = function (dict) {
    return dict.show;
};

var showString = new Show(function (s) {
    return s;
});

var showBoolean = new Show(function (v) {
    if (v) {
        return "true";
    };
    if (!v) {
        return "false";
    };
    throw new Error("Failed pattern match at Main line 12, column 1 - line 12, column 37: " + [ v.constructor.name ]);
});

var showArray = function (dictShow) {
    return new Show(function (xs) {
        return "[" + (Data_String.joinWith(", ")(Data_Functor.map(Data_Functor.functorArray)(show(dictShow))(xs)) + "]");
    });
};

var example = show(showArray(showBoolean))([ true, false ]);

这里绝对没有什么魔力,只是一些额外的参数。在“顶部”,您实际上知道具体的类型,您必须传入匹配的具体见证对象。

在您的示例中,您将传递不同形式的类似HasValue见证的内容。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53276744

复制
相关文章
OOP in Javascript
写了几篇Vue入门的内容了,今天写点其它的放松一下,简单讲讲javascript中的面相对象。 在面向对象的语言中,都有类的概念,当然es6中开始javascript中也有类的概念了,这里以es5为基础开始讲解,毕竟当前即使写的es6代码,一般还是会通过babel等转码器翻译到es5来执行的; 在js中虽然没有类的概念,但是我们却可以创建对象,一般创建对象有两种方式(这里指自定义对象): 1、使用构造函数 function Person(){ } var p=new Person(); 2、使用字面量
Jerremy
2018/06/13
4860
JavaScript之使用JavaScript模仿oop编程
第一, 首先,使用关键字function定义一个类 function Shape1(ax,ay) {//此时将function看成声明类的标志 var x=0; var y=0; var init=function () {//构造函数 对内部的变量赋值 x=ax; y=ay; } init();//构造函数的调用 this.getX=function () {//this声明公有函数 var 声明私有 get方法
wfaceboss
2019/04/08
4620
Python 面向对象编程(OOP)—— 类
在面向对象编程中,“类”就像一个函数,尽管普通的函数就可以用于整个程序,在OOP中,我们必须创建包含类中数据的“对象”,然后才能使用
Gorit
2021/12/09
5350
Python 面向对象编程(OOP)—— 类
Python中类-带括号与不带括号的区别
  有时候看到群里一些人问一些基础的知识,虽然很基础,网上随便一查即可知道,但是往往很多人就是连这些基础的知识都很模糊,甚至不清楚,这里再来复习一下python中类的一个知识点(仅此)。
全栈测试开发日记
2023/02/02
2.6K0
C++OOP对象和类
本文将从入门的角度介绍C++OOP中的类和对象,事实上C++的类和对象远远不止本文所介绍的内容。
SimpleAstronaut
2022/08/09
4020
C++OOP对象和类
OOP 长方柱类(类和对象)Python实现
编写基于对象的程序,求长方柱(Bulk)的体积。数据成员包括长(length)、宽(width)、高(heigth)、体积,要求用成员函数实现下面的功能:
叶茂林
2023/07/30
1420
Python面向对象编程(OOP) —— 导入类
前面我们讲过导入模块的方法(如何导入模块呢?),其实模块就是在同一个根目录下的 一个Python 文件,类 也是如此,Python 允许你讲类存储在模块中,然后在主程序中导入所需要的模块
Gorit
2021/12/09
6210
Python面向对象编程(OOP) —— 导入类
Java--多态性之嵌套类
上一篇:多态性之内部类和匿名类 嵌套类: 嵌套类即 static 内部类,必须记住内部类的对象默认持有创建它的那个封装类的一个对象的句柄。然而,假如我们说一个内部类是static 的,这种说法却是不成立的。嵌套类意味着: 为创建一个 static 内部类的对象,我们不需要一个外部类对象 不能从嵌套类的对象中访问非静态的外围类对象 嵌套内部类和普通内部类还有一个区别。普通内部类不能含有static数据和static字段,也不能包含嵌套类。但嵌套类可以包含这些东西。 静态内部类才可以声明静态方法  静态方法不可
SuperHeroes
2018/05/22
5640
实现类的多态性,方法的重写和重载
1.多态性是面向对象程序设计的重要部分。在Java语言中,通过使用方法的重载和重写实现类的多态性。
软件小生活
2021/08/16
7300
实现类的多态性,方法的重写和重载
Yet Another OOP : 基于原型而非基于类
OOP是一种程序设计的范式,是设计思想,在多种现代编程语言中都提供语法支持。然而,OOP就只是我们所知道的封装继承多态吗? 套用OOP的说法,OOP的设计思想是抽象,而OOP的编程语法只是实现。 OO
朝闻君
2021/11/22
3570
Yet Another OOP : 基于原型而非基于类
Java--多态性之抽象类和接口
上一篇:多态性之上溯造型和下溯造型 抽象类(abstract)可以含有一个或多个抽象方法(只有方法的定义而没有方法的实现),也可以不含有抽象方法。如果想从一个抽象类继承,而且新类要实例化对象,则必须实现抽象类的所有抽象方法。否则,新类也是抽象类。 接口(interface)可以理解为纯抽象类。它完全禁止方法的实现。接口中的数据成员(字段)默认为static和final, 成员函数(方法)默认为public。所以在实现一个接口时,来自接口的方法必须也是public。 实现按一个接口要使用 implements
SuperHeroes
2018/05/22
5450
JavaScript OOP(一)之构造函数与new命令
 面向对象编程:Object Oriented Programming,简称OOP。 典型的oop语言,如hava、c++,存在着类的概念,类就是对象的模板 (类可以类比为人类;而实例化类后变为对象,对象可以类比为男人;其实男人还可以作为一个类,小明是男人这个类的实例化对象) 而在JavaScript语言中,构造函数充当着对象的模板作用 JavaScript对象体系,是基于“构造函数”(constructor)和“原型对象”(prototype)的,不是基于类 使用构造函数和new示例: 1 var O1
用户1149564
2018/01/11
5440
JavaScript OOP(一)之构造函数与new命令
Java--多态性之内部类和匿名类
上一篇:多态性之抽象类和接口 为什么使用内部类: 每个内部类都可以独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了一个(接口的)实现,对内部类都没有影响。 如果没有内部类提供的、可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得更加完整。接口解决了部分问题,而内部类有效地实现了”多重继承“。也就是说,内部类允许继承多个非接口类型(类或抽象类)。 定义在一个类内部的类被称为内部类。内部类拥有对封装类所有元素的访问权限,因为内部类的对象默
SuperHeroes
2018/05/22
6390
什么是面向对象编程?OOP 深入解释
面向对象编程 (OOP) 是一种基本的编程范式,几乎每个开发人员都在其职业生涯的某个阶段使用过。OOP 是用于软件开发的最流行的编程范例,并且在大多数程序员的教育生涯中被作为标准编码方式教授。 另一种流行的编程范式是函数式编程,但我们现在不讨论它。
用户4235284
2023/10/14
1.2K0
什么是面向对象编程?OOP 深入解释
86-OOP之子类调用父类方法
如果子类和父类具有同名的方法,那么父类方法将被遮盖住。 可以在子类中明确指明调用的是父类方法,而不是子类的同名方法。
凯茜的老爸
2018/09/11
6590
Java抽象类与oop三大特征
在了解抽象类之前,先来了解一下抽象方法。抽象方法是一种特殊的方法:它 只有声明,而没有具体的实现 。抽象方法的声明格式为:
Java团长
2018/07/23
8050
Java抽象类与oop三大特征
jvm底层-类加载与oop-klass模型
从继承关系上也能看出来,类的元信息是存储在原空间(MetespaceObj)。
lovelife110
2021/02/24
6780
jvm底层-类加载与oop-klass模型
objective-C 的OOP(上)--类定义、继承及方法调用
上一篇展示了如何用传统的“面向过程编程方法”,实现画“矩形”、“圆”、“椭圆”,这一篇看下如何改用OOP的方法来实现: 因为要用到“颜色”以及“矩形区域”二个枚举,先把他们抽出来单独放在CommDef
菩提树下的杨过
2018/01/22
1.2K0
objective-C 的OOP(上)--类定义、继承及方法调用
JavaScript OOP(三):prototype原型对象(即构造函数的prototype属性)
通过构造函数生成的实例化对象,无法共享属性或方法(即每个实例化对象上都有构造函数中的属性和方法);造成了一定的资源浪费 1 function Obj(name,age){ 2 this.name=name; 3 this.age=age; 4 this.func=function(){ 5 return 'this is a test function'; 6 }; 7 } 8 var o1=new Obj('小明',10); 9 var o
用户1149564
2018/01/11
1.1K0
JavaScript OOP(三):prototype原型对象(即构造函数的prototype属性)
JavaScript OOP(二):this关键字以及call、apply、bind
JavaScript的this关键字非常灵活! this 返回的总是对象;即返回属性或方法“当前”所在的对象 1 var o1={ 2 name:'apple', 3 age:100, 4 msg:function(){ 5 return '显示name和age信息:'+'name: '+this.name+', age: '+this.age; 6 } 7 }; 8 //针对msg中的this进行研究: 9 console.log(o1.m
用户1149564
2018/01/11
5500
JavaScript OOP(二):this关键字以及call、apply、bind

相似问题

oop的多态性

10

不带多态性的抽象基类

60

python oop多态性

21

PHP、OOP、多态性

11

javascript oop多个类

21
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文