Javascript面向对象编程指南(一)

/*
ES5中除了引入一些新的对象与属性外,他还提供了“严格模式”,所谓严格模式就是在ES5发布之前,世面上个版本互不兼容语言的子集。严格模式就是可选的,也就是说,选择以严格模式执行的代码(以函数为单位,或者整个程序)都必须在其头部作一下声明:
“user strick”;
或许在以后的版本中,严格模式有个能成为ES的默认格式,甚至是唯一模式但现在它还是一个可选项。
*/

面向对象的程序设计


在深入学习Javascript之前,我们首相要了解一下“面向对象”的具体含义,以及这种程序设计风格的主要特征。下面我们列出一系列面向对象程序设计(OOP)中最常用到的概念:

  • 对象、方法、属性;
  • 类;
  • 封装;
  • 聚合;
  • 重用与继承;
  • 多态。

对象

所谓对象,实际上就是指“事物”(包括人和物)在程序设计语言中的表现形式。这里的“事物”可以是任何东西(如某个客观存在的对象,或者某些较为抽象的概念)。例如对于猫这种常见的对象来说,我们可以看到他们具有某些明确的特征(如颜色、名字、体型等),能执行某些动作(如喵喵叫、睡觉、躲起来、逃跑等)。在OOP语义中,这些对象特征都叫做属性,而那些动作则被称为方法。

此外,我们还有个一口语方面的类比:

  • 对象往往是用名词来表示的
  • 方法一般都是些动词
  • 属性值则往往是一些形容词

我们可以试一下。例如“一只黑色的猫在我头上睡觉”这个句子中,“猫”就是一个对象,“黑色”则是一个颜色属性值,而“睡觉”则是一个动作,也就是OOP语义中的方法。甚至,为了进一步证明这种类比的合理性,我们也将句子中的“在我头上”看作动作“睡觉”的一个限定条件,因此,它也可以被当作被传递给“睡觉”方法的一个参数。

在现实生活中,相似对象之间往往都有一些共同的组成特征。列如蜂鸟和老鹰都具有鸟类的特征,因此他们可以被统称为鸟类。在OOP中类实际上就是对象的设计蓝图或制作配方。“对象”这个词我们有时候也叫做“实例”。所以我们可以说老鹰是鸟类的一个实例。我们可以基于同一个类创建处许多不同的对象。因为类更多的是一种模板,而对象则是在这些模板上被创建出来的实体。

但我们要明白,Javascript压根就没有类。该语言的一切都是基于对象,其依靠的是一套原型(protoetype)系统。而原型本身实际上也是一种对象,我们后面也会来详细讨论这个问题。在传统的面向对象的语言中,我们一般会这样描述自己的做法:“我基于person类创建个一个叫做Bob的新对象”。而在这种基于原型的面向对象语言中,我们则要这样描述:“我将现有的person对象扩展成了一个叫做Bob的新对象”。

封装

封装是另一个与OOP相关的概念,其主要用于阐述对象中所包含的内容。封装的概念通常由两部分组成。

  • 相关的数据(用于存储属性)
  • 基于这些数据所能做的事(所能调用的方法)

除此之外,这个术语中还有另一层信息隐藏的概念,这完全是另一方面的问题。因此我们在理解这个概念时,必须要留意它在OOP中的具体语境。

以一个MP3播放器为例。如果我们假设它是一个对象,那么作为该对象的用户,我们需要一些类似与像按钮、显示屏这样的接口。这些接口会帮助我们使用该对象(如播放歌曲等)。至于他们内部是如何工作的,我们并不清楚,而且大多数情况下也不会在乎这些。换句话说,这些接口的实现对我来说的隐藏的。同样的,在OOP中也是如此。当我们在代码中调用一个对象的方法时,无论该对象是来自我们自己实现还是某个第三方库,我们都不需要知道该方法是如何工作的。在编译型语言中,我们甚至都无法查看这些对象的工作代码。

聚合

所谓聚合,有时候也叫做组合。实际上是指我们将几个现有对象合并成一个新对象的过程。总之,这个概念所强调的就是这种将多个对象合而为一的能力。通过聚合这种强有力的方法,我们可以将一个问题分解成多个更小的问题。这样一来,问题就会显的更易于管理(便于我们各个击破)。当一个问题域的复杂过程令我们难以接受时,我就就可以考虑将它分成若干个子问题区,并且必要的话,这些问题区还可以继续分解成更小的分区。这样做有利于我们从几个不同的抽象层来乐了从这个问题。

例如,个人电脑是一个非常复杂的对象,我们不可能知道它启动时所发生的全部事情。但如果我们将这个问题的抽象级别降低到一定的程度,只关注它几个组件对象的初始化工作,例如显示器对象、鼠标对象、键盘对象等,我们就很容易深入了解这些子对象情况,然后再将这些部分的结构合并起来,之前的那个复杂的问题就迎刃而解了。

继承

通过继承这种方式,我们可以非常优雅的实现对现有代码的重用。例如我们有一个叫做Person的一般性对象,其中包含一些姓名、出生日期之类的属性,以及一些功能性的函数,如步行、谈话、睡觉、吃饭等。然后当我们发现自己需要一个Programmer对象时,当然,这时候你可以再将Person对象中所有的方法与属性重新实现一遍,但除此之外还有一种更聪明的做法,即我们可以让Programmer继承自Person,这样就省去了我们不少工作。因为Programmer对象只需要实现属于它自己的那部分特殊功能(例如“编写代码”),而其余部分只需要重用Person的实现即可。

在传统的OOP环境中,继承通常指的时类与类之间的关系,但由于JS中不存在类,因此它的继承只发生在对象之间。

当一个对象继承自另一个对象时,通常会往其中加入新的方法,以扩展被继承的老对象。我们通常将这一过程称之为“B继承自A”或“B扩展自A”。另外对于新对象来说,它可以根据自己的需要从继承的那组方法中选择几个来重新定义。这样做并不会改变对象的接口,因为其方法名是相同的,只不过当我们调用新对象时,该方法的行为与之前的不同了。我们将这种重定义继承方法的过程叫做覆写。

多态

在之前的例子中,我们的Programmer对象继承了上一级对象Person的所有方法。这意为着这两个对象都实现了“talk”等方法。现在,我们的代码中有一个叫做Bob的变量,即便我们不知道它是一个Person对象还是一个Programmer对象情况下,也依然可以直接调用该对象的“talk”方法,而不必担心这会影响代码的正常工作。类似这种不同对象通过相同的方法调用来实现各自行为的能力,我们就称之为多态。

OOP小结

特征描述相应概念
Bob是一个男人对象
Bob出生于1990年,男性黑头发属性
Bob能吃饭、睡觉、喝水、做梦,以及记录自己的年龄方法
Bob是Programmer类的一个实例传统OOP中的类
Bob是一个由Programmer对象扩展而来的新对象基于原型OOP中的原型对象
Bob对象包含了数据(出生日期等)和基于这些数据的方法
(例如记录年龄)
封装
我们并不需要知道其记录年龄的方法是如何实现的。对象通
常都可以拥有一个私有数据,例如对闰年二月的天数,我们就不知道,而且也不会想知道
信息隐藏
Bob只是整个WEB开发团队对象的一部分,此外开发团队还包
含了一个Designer对象Jill,以及一个ProjectManager对象Jack
聚合、组合
Designer、ProjectManager、Programmer都是分别扩展
自Person对象的新对象
继承
我们可以随时调用Bob、Jill和Jack这三个对象各自的talk
方法,他们都可以正常工作,尽管这些方法会产生不同的结果
(如Bob可能谈的更多的是代码性能,Jill更倾向于谈代码的优雅性,而Jack强调的是最后期限)。
总之,每个对象都可以重新自定义他们的继承方法talk
多态、方法覆写
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值