征服 JavaScript 面试:类继承和原型继承的区别

来源:http://www.sh-fengwen.com 作者: 营养排行 人气:179 发布时间:2019-11-12
摘要:征服 JavaScript 面试:类继承和原型继承的区别 2017/01/30 · JavaScript· 继承 原文出处: EricElliott   译文出处:众成翻译    图-电子吉他-Feliciano Guimarães(CC BY 2.0) “征服JavaScript面试”

征服 JavaScript 面试:类继承和原型继承的区别

2017/01/30 · JavaScript · 继承

原文出处: Eric Elliott   译文出处:众成翻译   

图片 1

图-电子吉他-Feliciano Guimarães(CC BY 2.0)

“征服JavaScript面试”是我所写的一个系列文章,旨在帮助那些应聘中、高级JavaScript开发职位的读者们准备一些常见的面试问题。我自己在实际面试当中也经常会问到这类问题。系列的第一篇文章请参见“什么是闭包”

注:本文均以ES6标准做代码举例。如果想了解ES6,可以参阅“ES6学习指南”

原文链接:https://medium.com/javascript-scene/master-the-javascript-interview-what-s-the-difference-between-class-prototypal-inheritance-e4cd0a7562e9#.d84c324od

对象在JavaScript语言中使用十分广泛,学会如何有效地运用对象,有助于工作效率的提升。而不良的面向对象设计,可能会导致代码工程的失败,更严重的话还会引发整个公司悲剧

不同于其它大部分语言,JavaScript是基于原型的对象系统,而不是基于。遗憾的是,大多数JavaScript开发者对其对象系统理解不到位,或者难以良好地应用,总想按照类的方式使用,其结果将导致代码里的对象使用混乱不堪。所以JavaScript开发者最好对原型和类都能有所了解。

我曾尝试理解关于prototype的相关概念,最初理解起来晦涩难懂,加上当时用的地方又少。后面渐渐明白,当你需要了解一个东西的时候,刻意的去理解是没有本质的作用的,但是能在你的脑海里留下一丝印象,当你真正遇到的时候,会想起曾经看到过,时机成熟的时候再去理解,会有不少收获,轮番看个几遍,拿上实例解析,会发现豁然开朗。

类继承和原型继承有何区别?

这个问题比较复杂,大家有可能会在评论区各抒己见、莫衷一是。因此,列位看官需要打起十二分的精神学习个中差异,并将所学良好地运用到实践当中去。

类继承:可以把类比作一张蓝图,它描绘了被创建对象的属性及特征。

众所周知,使用new关键字调用构造函数可以创建类的实例。在ES6中,不用class关键字也可以实现类继承。像Java语言中类的概念,从技术上来说在JavaScript中并不存在。不过JavaScript借鉴了构造函数的思想。ES6中的class关键字,相当于是建立在构造函数之上的一种封装,其本质依旧是函数。

JavaScript

class Foo {} typeof Foo // 'function'

1
2
class Foo {}
typeof Foo // 'function'

虽然JavaScript中的类继承的实现建立在原型继承之上,但是并不意味二者具有相同的功能:

JavaScript的类继承使用原型链来连接子类和父类的 [[Prototype]],从而形成代理模式。通常情况下,super()_构造函数也会被调用。这种机制,形成了单一继承结构,以及面向对象设计中最紧密的耦合行为

“类之间的继承关系,导致了子类间的相互关联,从而形成了——基于层级的分类。”

原型继承: 原型是工作对象的实例。对象直接从其他对象继承属性。

原型继承模式下,对象实例可以由多个对象源所组成。这样就使得继承变得更加灵活且[[Prototype]]代理层级较浅。换言之,对于基于原型继承的面向对象设计,不会产生层级分类这样的副作用——这是区别于类继承的关键所在。

对象实例通常由工厂函数或者Object.create()来创建,也可以直接使用Object字面定义。

原型是工作对象的实例。对象直接从其他对象继承属性。”

本文阐述的相关内容:

为什么搞清楚类继承和原型继承很重要?

继承,本质上讲是一种代码重用机制——各种对象可以借此来共享代码。如果代码共享的方式选择不当,将会引发很多问题,如:

使用类继承,会产生父-子对象分类的副作用

这种类继承的层次划分体系,对于新用例将不可避免地出现问题。而且基类的过度派生,也会导致脆弱基类问题,其错误将难以修复。事实上,类继承会引发面向对象程序设计领域的诸多问题:

  • 紧耦合问题(在面向对象设计中,类继承是耦合最严重的一种设计),紧耦合还会引发另一个问题:
  • 脆弱基类问题
  • 层级僵化问题(新用例的出现,最终会使所有涉及到的继承层次上都出现问题)
  • 必然重复性问题(因为层级僵化,为了适应新用例,往往只能复制,而不能修改已有代码)
  • 大猩猩-香蕉问题(你想要的是一个香蕉,但是最终到的却是一个拿着香蕉的大猩猩,还有整个丛林)

对于这些问题我曾做过深入探讨:“类继承已是明日黄花——探究基于原型的面向对象编程思想”

“优先选择对象组合而不是类继承。” ~先驱四人,《设计模式:可复用面向对象软件之道》

里面很好地总结了:

  • 创建对象的几种模式以及创建的过程
  • 原型链prototype的理解,以及prototype__proto__[[Prototype]])的关系
  • 继承的几种实现

是否所有的继承方式都有问题?

人们说“优先选择对象组合而不是继承”的时候,其实是要表达“优先选择对象组合而不是类继承”(引用自《设计模式》的原文)。该思想在面向对象设计领域属于普遍共识,因为类继承方式的先天缺陷,会导致很多问题。人们在谈到继承的时候,总是习惯性地省略这个字,给人的感觉像是在针对所有的继承方式,而事实上并非如此。

因为大部分的继承方式还是很棒的。


本文由美高梅游戏平台网站发布于 营养排行,转载请注明出处:征服 JavaScript 面试:类继承和原型继承的区别

关键词:

最火资讯