并不是说 JS 的类有问题,但是如果你使用该语言已有一段时间,特别是使用过ES5,那么你可能就知道了从原型继承到当前类模型的演变。

原型链会有什么问题?

以我的拙见,这个问题的答案是:没有。但是社区花了很多年的时间才将类的概念强加到不同的结构和库中,因此ECMA技术委员会决定无论如何都要添加它。

你会问,这有什么问题吗?这就是他们真正做的,在我们已经拥有的原型继承之上添加了一些构成,并决定将其称为类,这反过来又让开发人员认为他们正在处理一种面向对象的语言,而实际上它们并不是。

类只不过是语法糖

jS 没有完全的 OOP 支持,它从来没有,这是因为它从来都不需要它。

表面上,当前版本的类显示OOP范例,因为:

  1. 我们可以创建基本的类定义,用非常经典的语法将状态和行为分组在一起。
  1. 我们可以从一个类继承到另一个类。
  1. 我们可以在公有和私有之间定义属性和方法的可见性(尽管私有字段仍然是一个实验性的特性)。
  1. 我们可以为属性定义getter和setter。
  1. 我们可以实例化类。

那么为什么我说类是语法糖呢?因为尽管在表面上,它们看起来是非常面向对象的,但是如果我们试图做一些超出它们可能的事情,比如定义一个类扩展两个类(目前不可能的事情),我们需要使用下面的代码

// 辅助函数
function applyMixins(derivedCtor, baseCtors) { baseCtors.forEach(baseCtor => { Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { let descriptor = Object.getOwnPropertyDescriptor(baseCtor.prototype, name) Object.defineProperty(derivedCtor.prototype, name, descriptor); }); });
} class A { methodA () { console.log('A') }
} class B { methodB () { console.log('B') }
} class C { }
// 使用 mixins

我们需要这样做,因为在JS中我们无法编写:

class A { methodA(){ console.log("A") }
} class B { methodB(){ console.log("B") }
} class C extends A, B { }

在上面的示例中,关键部分应该是applyMixins函数。如果,你没有完全理解它试图做什么,但可以清楚地看到它正在访问所有类的原型属性来复制和重新分配方法和属性。这就是我们需要看到真相的地方:类只不过是在经过验证的原型继承模型之上的语法糖。

这是否意味着我们应该停止使用类?当然不是,重要的是要理解它,而且如果我们想做些突破类的限制,那么我们就必须用原型来处理。

JS 的OOP 模型缺失了什么呢?

如果我们当前的OOP模型是如此之薄,仅是原型继承的抽象层,那么我们到底缺少什么呢?是什么让JS真正成为OOP?

看这个问题的一个好方法就是看看TypeScript在做什么。该语言背后的团队通过创建一些可以翻译成JS的东西,无疑将 JS 推向了极限。这反过来也限制了它们的能力。

目前 JS 中缺失的一些OOP构造具有内在的类型检查功能,在动态类型语言中没有真正的意义,这可能是它们还没有被添加的原因。

接口

接口可帮助定义类应遵循的API。接口的主要好处之一是,我们可以定义实现相同接口的任何类的变量,然后安全地调用其任何方法。

interface Animal { speak()
} class Dog implements Animal{ speak() { console.log("Woof!") }
} class Cat implements Animal{ speak() { console.log("Meau!") }
} class Human implements Animal{ speak() { console.log("Hey dude, what's up?") }
}

//如果我们在JS中有接口,我们可以放心地做:
let objects = [new Dog(), new Cat(), new Human()]
objects.forEach(o => o.speak())
当然,我们可以通过定义speak方法并覆盖它的类来实现同样的目的,但接口更加清晰和优雅。

抽象类

每当我尝试对我的代码进行完整的OOP操作时,我肯定会错过JS中的抽象类。抽象类是定义和实现方法的类,但永远不会实例化。这是一种可以扩展但从未直接使用的常见行为的分组方式。这是一个很好的资源,并且绝对可以在当前JS领域内实现而不会花费太多精力。

静态多态

静态多态性使我们可以在相同的类中多次定义相同的方法,但是具有不同的签名。换句话说,重复该名称,但要确保其接收不同的参数。现在我们有了JS的rest参数,这使我们可以拥有一个任意数字,但是,这也意味着我们必须在方法中添加额外的代码来处理这种动态性。相反,我们可以更清楚地区分方法签名,则可以将相同行为的不同含义直接封装到不同方法中。

左边的版本不是有效的JS,但它提供了一个更干净的代码,因此,阅读和理解起来比较容易。右边的版本是完全有效的,它阅读起来相对困难些,还要懂得一些 ES6 的语法。

多态性通常是通过查看方法中接收到的参数的类型来实现的。但是,由于JS的工作原理,我们知道这是不可能的。

受保护的属性和方法

我们已经有了公开的可见性,而且我们很快就得到了方法和属性的私有可见性(通过#前缀)。我认为下一步应该是添加受保护的可见性,然而,现在还没有,我认为如果你想要有一个合适的OOP体验,这三个都是必要的。受保护的属性和方法只能从类内部或它的一个子类中访问(与私有可见性相反,私有可见性将访问限制为只能访问父类)。

JavaScript类的问题相关推荐

  1. Javascript类的写法

    Javascript中function即为类,在function内部用this设置类的public成员变量与方法,例如: [javascript] view plaincopy function my ...

  2. 深入理解JavaScript类数组

    起因 写这篇博客的起因,是我在知乎上回答一个问题时,说自己在学前端时把<JavaScript高级程序设计>看了好几遍. 于是在评论区中,出现了如下的对话: 天啦噜,这话说的,宝宝感觉到的, ...

  3. 【Infragistics教程】在javascript类中添加静态成员属性

    2019独角兽企业重金招聘Python工程师标准>>> [下载Infragistics Ultimate最新版本] 在一个javascript类中创建一个属性的需求,它需要被所有对象 ...

  4. JavaScript OOP(2)定义JavaScript类

    JavaScript OOP(2)定义JavaScript类 5.1.7 定义类的方式(工厂方式.构造函数.原型方式.混合方式) 在面向对象的开发中,类被认为是对象的模板.在JavaScript中,可 ...

  5. JavaScript学习总结(十三)——极简主义法编写JavaScript类

    前两天在网上无意中发现了一篇使用极简主义法定义JavaScript类的文章,原文链接,这个所谓的"极简主义法"我还是第一次听说,是荷兰程序员Gabor de Mooij提出来的,这 ...

  6. JavaScript类的几种写法

    我们常用的有以下几种方法来用JavaScript写一个"类": 1. 构造函数(public属性和方法) 1: function Person(iName, iAge){ 2: t ...

  7. Javascript类的创建

    Javascript类的创建有两种方式 一.声明一个函数保存在变量里,然后在这个函数的内部通过对this添加属性和方法来实现对类添加属性和方法. var Book = function (id,boo ...

  8. JavaScript类与原型——组织JavaScript代码

    JavaScript的原型概念 为了本文的目的,最好先讨论JavaScript中的原型概念. 在JavaScript中,所有对象都从原型继承属性和方法.让我们考虑以下原型示例: functionVeh ...

  9. VML实现的饼图(JavaScript类封装)

    代码如下:<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft- ...

  10. 由浅到深了解JavaScript类

    无忧的老帖,不过价值不老,可以看看!! 作者:泣红亭 许多刚接触编程的朋友都可能理解不了类,其实类是对我们这个现实世界的模拟,把它说成"类别"或者"类型"可能会 ...

最新文章

  1. linux共享内存的定义,共享内存是什么意思 Linux系统如何共享内存
  2. Java后端开发需要具备哪些知识结构
  3. jq之$(“tr:even“).css(“background-color“,“yellow“)
  4. 【Flink】Flink Serving 天池快速上手 【视频笔记】
  5. [Ceoi2010]Pin
  6. always on sql 收缩日志_sql server日志文件过大无法收缩的问题
  7. 2016012052+小学四则运算练习软件项目报告
  8. linux管理进程的数据结构,Linux 进程运行的各项指标的监测和一些管理命令的应用...
  9. 高职计算机专业英语词汇,高职计算机专业英语词汇的学习方法
  10. 如何将Excel表格进行美化?学会这几招你的表格将不会那么难看
  11. 《Linux那些事儿之我是USB》我是U盘(14)冰冻三尺非一日之寒
  12. 关于travis scott的网名_2020微信情侣名字情侣专用 霸气秀恩爱的情侣网名
  13. android6最新版本,安卓版“AirDrop”发布,安卓6版本以上都能用!
  14. 纹波测试方法(收集整理)
  15. LeetCode/LintCode 题解丨一周爆刷双指针:最小范围
  16. 网页点名器(移动端、pc端)
  17. 分享上海seo统计的seo基础知识
  18. Android Studio2.2 CMAKE高效NDK开发
  19. win10进入系统后只有鼠标箭头,桌面全黑(文件系统错误-2018374635)
  20. 盛迈坤电商:拼多多营销策划的方法

热门文章

  1. 神经网络“天生”就会驾驶虚拟赛车
  2. 【每日一算法】使用二分法解决x 的平方根问题
  3. Flask-RESTful之视图
  4. Python在ubuntu中更改Python和pip指向
  5. 再次学习基础爬虫,爬取大学排名。
  6. 实战centos6安装zabbix-2.4版(终极版)
  7. caffe这个c++工程的目录结构
  8. 2014年:这些词都快被玩坏了
  9. Compressor detection can only be called on some ……
  10. FreeSwitch 的初始化及其模块加载过程