JavaScript对象:我们真的需要模拟类吗?
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
JavaScript的面向对象编程方式一直备受争议,特别是在模拟类的实现上。早期的JavaScript程序员常常使用“模拟面向对象”的方式来实现类似于基于类的面向对象编程,但随着对JavaScript的深入理解,人们开始意识到这种模拟实际上是在“模拟基于类的面向对象”。JavaScript的原型系统相当简单,通过原型可以实现抽象和复用。从历史上看,JavaScript的原型系统与高动态性语言配合,多数基于原型的语言提倡运行时的原型修改,这也是Brendan选择原型系统的重要理由之一。幸运的是,从ES6开始,JavaScript提供了class关键字来定义类,统一了社区的方案,修正了之前的一些“坑”,对语言的发展有着非常大的好处。ES6中引入了新特性class,new跟function搭配的怪异行为终于可以退休了(虽然运行时没有改变),在任何场景,我都推荐使用ES6的语法来定义类,而令function回归原本的函数语义。总的来说,JavaScript的原型系统虽然曾经使用类似于Java的复杂语法设施来模拟类,但实际上原型系统相当简单,通过原型可以实现抽象和复用。随着ES6的到来,JavaScript提供了class关键字来定义类,统一了社区的方案,对语言的发展有着非常大的好处。在新的ES版本中,我们不再需要模拟类了:我们有了光明正大的新语法。而原型体系同时作为一种编程范式和运行时机制存在。我们可以自由选择原型或者类作为代码的抽象风格,但是无论我们选择哪种,理解运行时的原型系统都是很有必要的一件事。
《重学前端》,新⼈⾸单¥59
全部留言(140)
- 最新
- 精选
- 浩明啦置顶这些知识真的不止这个价格了, 感谢老师2019-01-316151
- 羲winter老师,有一些浏览器对es6语法部分不兼容,一般开发中依旧用新的es6语法,然后找插件转换成浏览器支持的语法,想问下,你对这种做法怎么看?这样做是不是有点兜圈子了,直接用旧语法也可以写,但又有些想尝试用新的语法
作者回复: 我比较支持这个做法,尽早使用新语法,可以享受它们带来的好处,也可以让团队始终保持技术领先。 当然了,少数情况下,没法完美翻译,我就不建议急着用了。
2019-02-137 - 雪中抱猪行JQ的‘$’兼具,对象,类(构造函数),函数三种角色。老师多这种用法持什么观点。
作者回复: 我持反对观点。 这个$的问题不仅仅在于兼具了三种角色,而且还把若干种毫不相干的功能放到了一个函数上,这几乎完全违反了程序设计的基本原则。 因此这个东西几乎已经完全脱离了几十年间计算机编程发展的理论支持,这样的设计注定了没法编写复杂应用。
2019-02-145 - lt-零度老师,我的留言都没回复过我,伤心
编辑回复: 别伤心,给你安排
2019-01-314 - F.老师,为什么直接输出 v.toString() 的结果和 Object.prototype.toString.call(v) 不一样
作者回复: 因为v的原型链上先有别的toString了呗
2019-02-1622 - 看啥看看不懂我感觉不是我们需要模拟类,而是我们需要真正类的形式。我认为单纯的原型形式去做项目,在复用,扩展方面不是很适合,比如 每次生成的对象没有办法判断是否从属一类;使用Object.create方法,会将对象的属性放在原型链上,这样该对象的私有属性就成了公共的,违背了属性最好私有化的开发概念。在开发中也容易出现bug。我感觉,类的想法很适合扩展,复用。原型链变为了它的内在实现方式。如果手动用原型链写,也可以实现,但就是麻烦些。
作者回复: 其实没有所谓的“真正类”这个说法,在面向对象概念复杂的演进历史中,并没有明确地形成这个共识。
2019-11-07 - LaMer“所有对象都有私有字段[[prototype]]” 这句不是很理解 我发现 现在chrome普通对象都是有_proto_字段 ,没发现[[prototype]]字段 望老师解答!!!!
作者回复: 既然是私有字段,你当然访问不到了。 __proto__确实是[[prototype]]的映射,但是这是早期浏览器违背标准提供的,现在已经没有必要,请用setPrototypeOf和getPrototypeOf
2019-10-142 - 奋奋老师好,关于原型系统两条概括的第一条,“如果所有对象都有私有字段[[prototype]],就是对象的原型”,这句话我反复阅读,也不能理解,所有对象是什么?怎么就成对象的原型了?望能再细说一下
作者回复: 额......“私有字段[[prototype]],就是对象的原型” 这俩是同位语。
2019-10-142 - Gavin 峰“类”并非面向对象的全部,如何理解?
作者回复: 这整篇不都在讲这个么
2019-08-032 - 八脚老师:听您课程受益匪浅,想问个问题我设计继承类的时候会经常在super前面对父类参数做加工,这样的做法是否合理,或者有更合适的做法? class 猫{ constroct({skin: 黑色, ...other}){ this.skin = skin; } ...... }; class 花斑虎 extends 猫 { constroct(config){ config.skin = 花斑; super(config); } ...... }
作者回复: 不合理,你需要考虑下花斑虎的花斑是否真的有必要放到类里面,它可能只是个属性而已。
2019-02-22