提问者的话
-
什么是面向对象,面向对象有哪些特点,以及这些特点的解释。
-
JavaScript 如何实现这些特点,比如封装、继承、多态。
- 如果关于上述三点,你能够解释到有多少种实现方式、优缺点是什么。
- 以及近几年流行的解决方案是什么。这就是加分
- 比如对于继承吧。类式继承、构造函数继承、组合继承、原型继承、寄生组合继承等
- 说出大概的实现思路和优缺点,再介绍下 extends 或者 mixin 的实现
- 甚至你可以衍生到JavaScript 的模块化发展
- 甚至到为什么现在 TS 如此流行。
- 那么可以说到这一环节解答的就非常棒了。
-
回答完 JavaScript 的面向对象,是不是可以从此衍生下为什么需要面向对象。
-
以及当先对于软件设计的高内聚、低耦合的思考?
-
来个对此题一个提纲挈领的总结?
JavaScript
中的对象不合群
-
JavaScript
中有对象的概念,但没有类的概念,ES6中的class
也只是一个语法糖 -
JavaScript
对象中可以自由添加(删除修改)属性 - 关于
面向对象
和基于对象
的争论- 这两个词都出现在
JavaScript
标准的各个版本中。 - 基于对象的定义:“语言和宿主的基础设施由对象来提供,并且
JavaScript
程序即是一系列互相通讯的对象集合” - 基于对象的定义并未弱化
面向对象
的意思,反而更加说明了对象对于语言的重要性
- 这两个词都出现在
什么是面向对象
-
Object
:一切皆对象 - 对象并不是计算机领域凭空造出来的概念,它是顺着人类思维模式产生的一种抽象
- 人的成长过程中先认识到对象,然后才有过程、值的概念【一个苹果(实例)可以吃——所有苹果(类)可以吃——3(值)个苹果和3个梨的关系】
- 所以
面对对象编程
是更接近人类思维的一种编程范式 - 最成功的流派使用类的方式来描述对象,如
JAVA
-
JavaScript
选择了较冷门的原型【因为一些公司政治原因,JavaScript 推出之时受管理层之命被要求模仿 Java,JavaScript 创始人 Brendan Eich 在“原型运行时”的基础上引入了 new、this 等语言特性,使之“看起来更像 Java”】 -
ES6
之前,很多人试图将JavaScript
变得更像基于类的语言,进而产生了很多所谓的“框架”,比如PrototypeJS、Dojo
【事实上,它们成为了某种 JavaScript 的古怪方言,甚至产生了一系列互不相容的社群,显然这样做的收益是远远小于损失的】 - 从运行角度谈论对象:任何代码执行都必定绕不开运行时的对象模型【运行时类的概念都是被弱化的】
-
JavaScript
面向对象编程:-
命名空间
是一个容器,它允许开发人员在一个独特的,特定于应用程序的名称下捆绑所有的功能。JavaScript
中,命名空间只是另一个包含方法、属性、对象的对象 - 注意:需要认识到重要的一点是:与其他面向对象编程语言不同的是,
Javascript
中的普通对象和命名空间在语言层面上没有区别。这点可能会让JavaScript
初学者感到迷惑。 - 创造的
JavaScript
命名空间背后的想法很简单:一个全局对象被创建,所有的变量,方法和功能成为该对象的属性。使用命名空间也最大程度地减少应用程序的名称冲突的可能性。 -
JavaScript
有包括在其核心的几个对象,例如,Math,Object,Array和String
对象
-
JavaScript
对象的特征
- 对象具有唯一标识性:即使是完全相同的两个对象,也并非是同一个对象
let o1 = {a: 1}
let o2 = {a: 1}
console.log(o1 == o2) //false
- 对象具有状态:同一对象可能处于不同的状态之下
- 对象具有行为:对象的状态可能因为它的行为而产生变迁
a) 状态和行为在不同的语言中使用不同的术语来描述
b) java中称为属性(状态)和方法(行为)
c) javascript中将状态和行为统一抽象为“属性”
d) javascript中函数是一种特殊的对象
let age = 20
let o = {
name: 'Lily',
sayHi(){
console.log('Hi')
}
}
- 除了上述3个基本特征外,
JavaScript
的独特之处:高度的动态性,运行时改变对象的状态和行为(属性)的能力 -
JavaScript
的属性比别的语言更复杂,它提供了数据属性和访问属性(getter/setter
)JavaScript
对象的两类属性
封装&多态
image-
在该案例中,
Student类
虽然不需要知道Person类的walk()
方法是如何实现的,但是仍然可以使用这个方法;Student类
不需要明确地定义这个方法,除非我们想改变它。 这就叫做封装,对于所有继承自父类的方法,只需要在子类中定义那些你想改变的即可。 -
有了封装来看多态
-
先定义父类和多个子类
image -
有个工厂,根据不同的类型来调用不同的子类
image
-
-
看看下面两篇文章,他们算是面向对象编程中的封装吗?
axios的封装
模块化的发展 ≈ 封装方式的发展?
-
vue组件的封装属于哪一类型的封装呢?
继承方案(继承的本质是复制)
image-
原型链继:多个实例对引用类型的操作会被篡改
image -
构造函数继承
image -
原型链+构造函数
image
image -
原型式&寄生式:这个就不具体看了,用
imageObject.create()
吧
-
构造函数+寄生式:看下继承章节第一张图片“组合式继承”
-
混入方式继承多个对象:
imageObject.assign
-
ES6
类class
的extends
阮一峰
imageES6
Class
的继承:包括extends
和Mixin
extends
继承的核心代码如下,其实现和上述的构造函数+寄生式
一样
function _inherits(subType, superType) {
// 创建对象,创建父类原型的一个副本
// 增强对象,弥补因重写原型而失去的默认的constructor 属性
// 指定对象,将新创建的对象赋值给子类的原型
subType.prototype = Object.create(superType && superType.prototype, {
constructor: {
value: subType,
enumerable: false,
writable: true,
configurable: true
}
});
if (superType) {
Object.setPrototypeOf
? Object.setPrototypeOf(subType, superType)
: subType.__proto__ = superType;
}
}
- 你用到继承了吗?
关于继承有人会问:虽然js的继承原理我知道,js代码我也一直在写,但是js的继承真的有用?写了这么久一直都没有用过,倒是看了下es6的继承感觉和java挺像,应该挺实用的,我知道自己水平不够,我想问一下js的继承一般用在哪呢?
- 来看下上面问题的简单答案:
- 举个简单粗暴的?,页面上可以弹出来的元素有
Modal/Tips/Alert/Confirm
这么几种,其实这几种元素都可以抽象成是一个具有show 和 hide
方法的元素,这个时候,我们就可以写个ModalCore
的对象,写好show 和 hide
方法。然后上面的几个元素对象,继承这个就好了。 - 我觉得,需要不需要,主要是取决于平时的工作需要吧,如果开发一些库的代码我猜八成会需要的,但是如果只是平时写一下页面什么的,很少需要,没有那么的抽象必要
- 根据二八原则,JavaScript 20% 的语法可以完成 80% 的功能,继承大概属于剩余的 80% 语法吧
- 本人自己用
ExtJs
的时候倒是经常用extends
;用VUE
封装组件和原来ExtJS的extends
挺像的;VUE
封装是调用一个旧的组件封装成新的组件比较多,用继承的方法较少
- 举个简单粗暴的?,页面上可以弹出来的元素有
...
软件的高内聚、低耦合:面向对象设计的七大原则
...
...
JavaScript设计模式:来自w3cshool
...
TypeScript
相关
结语
相对于「一个程序只是一些函数的集合,或简单的计算机指令列表。」的传统软件设计观念而言,面向对象编程可以看作是使用一系列对象相互协作的软件设计。 在 OOP
中,每个对象能够接收消息,处理数据和发送消息给其他对象。每个对象都可以被看作是一个拥有清晰角色或责任的独立小机器。
面向对象程序设计【允许开发人员在一个独特,应用相关的名字的名称下捆绑所有功能的容器】的目的是在编程中促进更好的灵活性和可维护性,在大型软件工程中广为流行。凭借其对模块化的重视,面向对象的代码开发更简单,更容易理解,相比非模块化编程方法, 它能更直接地分析, 编码和理解复杂的情况和过程。
网友评论