APP下载

JavaScript的面向对象特性分析

2017-07-14刘莲花陈瑛

电脑知识与技术 2017年16期
关键词:面向对象函数

刘莲花+陈瑛

摘要:传统面向对象的设计模式强调基于类的概念,而JavaScript不使用类。这让大多数开发者们在学习JavaScript的面向对象编程时候感到困惑。该文基于面向对象编程思想的本质,将JavaScript面向对象特性与传统面向对象语言进行比较分析,深入讨论了JavaScript的面向对象编程的特性。同时,用举例的方法阐述JavaScript是如何实现面向对象特性的。通过该文的分析,有利于大家对JavaScript面向对象特性的理解。

关键词:JavaScript;面向对象;原型对象;函数

是否精通JavaScript现已成为招聘Web开发人员的决定性因素。如果Web开发人员在面试时被问到这样的问题:“JavaS-cript是一种面向对象语言吗?如果是,JavaScript中的继承关系是如何实现的呢?在现实中,即使是做了很多年JavaScript开发的程序员对这个问题也说不清道不明。很多人能熟练地使用各种框架,但其代码组织却不是很理想,这是由于其对Ja-vaScript的原生语言特性如闭包、函数式编程、原型链等理解不够深人。本人在文献检索时发现,涉及JavaScript面向对象特性的主题文献不到10篇,其中黄华林等人提出“JavaScript是基于对象的语言,而非完全面向对象的。故JavaScript不可能实现面向对象语言的所有特性”的观点。这是对JavaScript面向对象特性的误解。在有关JavaScript的著作中,题名出现“面向对象”字样的不超过10本,很多关于JavaScript的经典著作也只是用很小的篇幅来简单阐述它的面向对象特性。对JavaScript来说,大家关心的只是它的各种跨平台应用,但不能因为JavaS-cript中没有用到类,或没有接口的概念,就认为它不是完全面向对象的。恰恰相反,正是由于JavaScript的面向对象特性,它才能如此的灵活,应用的如此广泛。所以要真正理解JavaScript的面向对象特性,应该基于面向对象编程思想的本质,结合Ja-vaScript自身的特点,从函数式编程及原型对象的角度来分析它的面向对象的特性。

本文从三个方面来展开分析讨论,一、面向对象编程思想的本质,二、JavaScript与传统基于类的面向对象语言的比较分析,三、JavaScript面向对象实现的举例说明。

1面向对象编程思想的本质

面向对象编程思想的本质体现在——面向对象编程语言必须包含这些特性:对象、属性(变量)、行为(方法)、类、封装、继承、多态等。面向对象编程思想的重点在“对象”上,对象实质上是“客观事物”在程序设计语言中的表现形式,客观事物可以是某个客观存在的人或物,或者某些抽象的概念。事物的静态特征称之为属性,而事物的动态行为或动作称之为方法。将具有相同属性和行为的一组对象的集合抽象成为类的概念,可以基于同一个类实例化许多不同的对象,类是模板,而对象是在这些模板的基础上被创建出来的实体。封装的本质是为了实现信息的隐藏,就是把对象的属性和行为结合成一个独立的整体,这样做可以将对象的设计与使用分开,使用对象时不用去关心其内部的信息,只需通过传递消息来访问对象。继承是指在已经存在的类的基础上,构造出新的类,它很好地实现了代码复用。多态是指不同对象通过调用名字相同的方法来实现各自行为的能力,这符合现实生活的习惯和要求,而且可以使程序更加简洁和一致。

面向对象是一种不依赖于某种语言而存在的编程思想。Java通过关键词class和extends很好地实现了面向对象编程,但并不是说这一思想只能通过这种方式来实现,一门编程语言可以借助其自身特点通过合适的某种方式来实现面向对象编程思想。所以,不能先入为主地认为基于类来实现面向对象的语言才是面向对象语言,而像JavaScfipt这样基于原型对象来实现面向对象的则不是面向对象语言。实际上,JavaScript虽然没有类的概念,没有class和extends关键词,但通过原型对象,它也实现了对象创建、封装、继承、多态等面向对象的特性。下面就来讨论基于类的面向对象和JavaScript基于原型对象的面向对象的差别。

2JavaScript与传统基于类的面向对象的比较分析

在基于类的面向对象方式中,通过类来创建多个同属性和行为的对象。而ECMAScirpt中没有类的概念,其中的对象与基于类的语言中的对象有所不同,ECMA-262将对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数。也就是说,JavaScript中的对象是一组“名一值”对,其中的值可以是数据,也可以是函数,当值是数据(变量)时,表示的是对象的属性,当值为函数时,表示的是对象的行为(方法)。这种基于原型对象的面向对象方式,对象是通过构造器函数利用原型对象构造出来的。以生产制造一辆机动车为例来说明这两种构造对象方式的差异。机械工程师设计出机动车的构造图纸,图纸详细规定了制作工艺及组装流程,工人依照图纸来生产制造。本例中的图纸就好比是基于类的面向对象语言中的类,而某辆车就是按照这个类制造出来的对象;而另一面,工人和机器利用各种零部件如发动机、车轮等将机动车组装制造出来,这里的零部件就如同是面向对象中的属性(可以是各种原生原型或对象),而机器相当于是构造器函数。

回到客观世界中,任意一个对象的产生都是通过其他已存在实物对象构造的结果,而抽象的“图纸”是不能产生“车子”的,也就是说,类是一个抽象概念而并非实体,而对象的构造是一个实体的产生;按照一切事物皆对象这个最基本的面向对象的法则来看,类本身并不是一个对象,而原型方式中的构造器和原型本身则是其他对象通过原型方式构造出来的对象。这更符合人们看待客观世界的方式,更能彻底地体现面向对象编程的思想。再者,在基于类的面向对象语言中,对象的属性值由每一个对象实例所独有,而对象的行为方法却统一在类内声明,由类拥有,在继承时,子类对象只能继承父类对象的结构和方法。而在基于原型的面向對象语言中,对象的行为、属性都属于对象本身,并且能够一起被继承,这也更贴近客观实际。

所以面向对象的编程思想除了能通过类来实现外,也可以通过其他的方式来实现,其中JavaScript就是这样的一种基于原型对象的面向对象语言,在接受了这一观点后,下面我们就举例来说明JavaScript是如何通过原型对象来实现面向对象的各种特性。

3基于原型对象实现面向对象的举例

3.1对象的创建

对象是面向对象编程的核心,比如:要定义一个机动车类,名字叫Vehicle,有两个属性:speed和wheelnum,另外有两个方法:一个~how0方法,用于显示机动车当前的信息,一个speedup()方法,用于加速,那么用Java语言可以如下来实现:

3.2封装的实现

封装是面向对象编程中的重要概念之一。下面我们通过一个具体的例子来讨论JavaScript是如何实现封装特性的。

在原型对象内部定义的属性和方法,其作用域只在原型内部,外部不能访问,这样的属性就是私有属性,方法就是私有方法。而在原型对象内部定义带有this修饰的属性和方法,或是通过原型对象的原生原型定义的属性和方法,其作用域不仅限于原型对象内部,那么这些属性和方法将成为公有属性和方法。在JavaScript中,对象的属性和方法可以动态地添加,正是因为这个,其要定义静态属性和方法是很容易的事情。

3.3继承的实现

JavaScript中没有实现继承的关键词extends,也没有严格地定义抽象类,但JavaScript通过语言本身的特性实现了继承。它支持多重继承,而且实现继承的方式也有很多种,如:对象冒充、通过call或apply、原型链及多种混合的方式,下面通过原型链的方式来实现继承,代码如下:

这种方式是通过创建一个父级对象赋给子级的prototype属性,子级对象就拥有了父级对象中的属性和方法,即实现了继承…。每个对象实例都有一个内部属性prototype,通过这个属性跟踪其原型对象,子级的原型对象的内部属性prototype获得了父级的一个对象实例,继续跟踪到了父级的原型对象,如此就形成了一个原型链。

3.4多态的实现

多态主要是通过方法的重载和覆盖来实现。重载是指名字相同的方法可以有多种不同的实现,主要通过参数的类型、参数的个数及参数的顺序的不同来识别。而JavaScript在函数定义时可以不指定函数参数的类型和个数,所以说它的本性就支持重载。而覆盖是指子类中可以定义与父类同签名的方法,子类对象调用这些方法时,从父类中继承过来的同名方法将被隐藏。

在上述实现继承的例子中,再定义一个car的子类(原型对象),实现代码如下:

4结束语

传统基于类的面向对象思维在一定程度上妨碍了大家对JavaSeript面向对象特性的理解,本文对面向对象编程的本质进行了分析,通过比较分析及举例说明的研究方法深入讨论了JavaScript的面向对象特性。它的弱类型,简单易用性、解释性及跨平台性,使其在Web的应用开发中可以说是无处不在,但它的无类动态对象、原型链继承、闭包等特性使其具有更高的灵活性。所以彻底地理解并应用JavaScript的面向對象特性是非常有意义和有必要的。

猜你喜欢

面向对象函数
二次函数
二次函数
函数备考精讲
面向对象的计算机网络设计软件系统的开发
面向对象的数据交换协议研究与应用
面向对象Web开发编程语言的的评估方法
面向对象信息提取中影像分割参数的选择