JavaScript面对对象程序设计
序言
基于对象还是面对对象?
面对对象技术是当代软件开发中的重要技术之一。面对对象变成的好处毋庸置疑,目前的主流语言如Java、C++都是面对对象的。目前的面对对象理论更多的是使用Java或C++进行描述,究其根源,在于这些语言都是老式的面对对象语言,具备面对对象理论所指明的一切特性:类、封装、继承、多态等等。
相比而言,某些动态语言如JavaSript就显得不那么面对对象——最少,在JavaScript中并没有类class这一核心字。不过,在JavaScript中并不是没有类的概念。于是有人说,JavaScript 是基于对象的语言,而不是面对对象的语言。
面对对象的语言具备三个特性:封装、继承和多态,三者缺一不可;基于对象的语言一般仅仅是使用对象,其实现的是封装,并没有提供后两种特性。确实,从语法上来说,JavaScript 并没有特定的语法或者在语言级别上来实现继承和多态。不过,这并不妨碍我们使用这些特性。这是因为,JavaScript是一个灵活的语言,它是相称的灵活,以至于这些并没有提供的东西,更确切的说,是没有明确的表白的东西,都是能够实现和使用的!那么,你还能说JavaScript是基于对象而不是面对对象的吗?
面对对象也是一个思想,任何语言,包括C语言,同样能够使用面对对象的思想去处理现实生活中的各种问题。到底是基于对象还是面对对象,这些概念让计算机哲学家门去争论吧——相信他们的争论最后也会和先有鸡还是先有蛋的问题同样的成果——我们所要做的,是要使用这种语言提供的机制去处理我们的问题。
为何要有JavaScript的面对对象编程?
这个问题很严肃——这取决你问题的规模和应用的范围。就像JavaEE和PHP同样:PHP
能实现的东西,JavaEE都能实现,那么,为何还要有PHP?因为JavaEE太复杂了,对于某些简单的系统,根本没有必要是使用它,也就是所谓的“杀鸡焉用牛刀”。
JavaScript重要应用于Web开发中。在老式的Web开发模式中,JavaScript起到的是某些点缀的作用,只完成很有限的功效,例如表单验证等。于是,JavaScript多被当做一个过程性语言使用,极难完成复杂的功效。而今日Web2.0的时代,Ajax大行其道,诸多复杂的脚本成为其必须的组成部分。在Ajax应用中利用JavaScript面对对象编程格调,能够使逻辑愈加清楚,也更有利于问题的处理。
假如你想用JavaScript编写一个库,例如ExtJS或者YUI,极难想象你的类库不使用面对对象的编程格调——否则的话,无论是对你还是对使用者的智力都将是一个前所未有的考验!或许,自从面对对象思想
提出之后,已经极难有类库不使用面对对象的方式实现了,即便是C语言的库诸如gtk+,也是用C语言将面对对象的思想体现的天衣无缝。面对对象的思想
对于大型程序的编写和使用具备不可替代的作用。
本系列文章将试图向读者论述JavaScript的面对对象程序设计。尽管JavaScript中具备诸多浏览器有关的概念,如document等内置对象,不过本系列将不包括这些问题,并且将假设读者已经有JavaScript基础的语法知识等。本系列文章不会从头开始讲述JavaScript的语法,仅仅从纯粹的面对对象角度审阅JavaScript,或许,你将会看到一个教程:面对对象程序设计——JavaScript 语言描述。这才是本系列文章的目标。
数组
或许你会奇怪,面对对象的程序设计为何从数组开始讲起?这是因为……其间的种种关系吧……嘿嘿,这里先卖个关子,先来看看我们熟悉的数组在JavaScript里面是什么样子的。
1. 创建数组
在JavaScript中有诸多创建数组的措施。例如使用Array函数。不过这不是目前我们要讲述的。目前我们使用简单的方括号“[]”的措施来创建数组。
var objAyyar = []; // 1
var objAyyar = [2]; // 2
var objAyyar = ["a", "b", "c"]; // 3
var objAyyar = [new Date(), 123, "abc"]; // 4
复制代码
这里有四个创建数组的语句。下面来一一解释一下:
第一句,创建一个空的数组;
第二句,创建一个数组,数组元素只有一个2;
第三句,创建一个数组,数组的元素分别初始化为"a", "b", "c";
第四句,创建一个数组,其中第一个元素为一个Date类型的对象,第二个元素是数字123,第三个元素是字符串"abc"。
回忆一下,在Java或者C++语言中,数组是具备相同的数据类型的元素的集合。例如使用Java语言的下面语句
int[] array = new int[10];
复制代码
将创建一个能放入10个int类型的元素的数组。数组和其他类型的集合的一个很大的区分
是,数组里面只能存储相同数据类型的元素(使用泛型的集合除外)。不过,像上面的第四句,JavaScript的数组怎么能存储不一样类型的元素呢?这是因为,JavaScript是弱类型的语言,没有很大的数据类型的差异,因此数组的元素能够放入不一样的类型。
2. 操作数组
数组是元素的有序集合。数组中的元素是有序的,这就能够通过下标访问到数组中的每个元素。并且,JavaScript的数组相称的灵活。当你习惯了Java或者C++的数组之后,或许并不习惯JavaScript的数组。在一定程度上,这种数组能够称为一个动态数组。看这么一段代码:var arr = [1, 2, 3, 4, 5];
alert(arr.length); // 数组长度为5
alert(arr[3]); // arr[3] = 4
arr[9] = 10; // 变化了数组的长度为10
alert(arr[7]);
alert(arr.length);
复制代码
首先创建一个数组arr,能够看到它的长度是5,arr[3]是4。这些都是很常见的。那么第三句,arr[9] = 10;就有点意思了——在Java中,这句操作将导致数组越界的异常,在C++中,这种操作是极其危险的。不过在JavaScript中,这么的操作是正常的——你能够动态的变化数组的大小!虽然你在创建数组时并没有这么大的长度,不过,你能够在创建之后指定它!这时的arr.length已经自动的变成10了。那么,arr[7]又会是什么呢?通过运行代码我们会看到,arr[7]是undefined。也就是说,虽然arr[9]有了值,不过其中从arr[5]到arr[8]这几个元素都是未定义的,也就是undefined。假如你问JavaScript怎么不给个初始值?唉,饶了它吧!JavaScript并不懂得你想要它初始化成什么值啊!万一错了呢?干脆还是别了吧……
var arr = [1, 2, 3, 4, 5];
alert(arr.length); // 数组长度为5
delete arr[3]; // 删掉第4个元素
alert(arr.length); // 长度不变
alert(arr[3]); // arr[3] = undefined
arr.length = 4; // 缩短长度
alert(arr[4]);
arr.length = 10; // 增加长度
alert(arr[6]);
复制代码
上面的代码也很故意思:使用delete操作符能够删除任意一个数组元素,不过长度并不变化。
Java的数组也有一个length属性,用来显示数组的长度。JavaScript的数组也有这个属性。不过,和Java不一样的是,后者的length属性并不是只读的!你能够任意的设置数组的length
属性的值,无论是扩大还是缩小!只是如上面的代码所示,变化了length之后,越界的元素或者此前没有定义的元素都将成为undefined。也就是说,当length不小于原始长度时,从原长度到length - 1的元素都将成为undefined;当length小于原始长度时,从length到原长度- 1的元素也都会清除设置为undefined。
3. 非数字的下标?
假如动态的length属性还不够灵活的话,那么,JavaScript的数组尚有另外的能力。
你见到过用字符串做数组下标的吗?Java行吗?C++行吗?JavaScript就行!看看下面的语句:
var arr = [1, 2, 3];
alert(arr[1] == arr["1"]);
arr["js"] = 4;
alert(arr["js"]);
复制代码
上面的语句看到,arr[1]和arr["1"]实际是同样的效果!这是怎么回事呢?我们用下面的语句验证一下:
alert(1 == "1"); // true
alert(1 === "1"); // false
复制代码
因为JavaScript是弱类型语言,因此在使用变量的时候,JavaScript会尽也许的将它转换成所需要的类型。例如数组下面需要数字,那么提供一个字符串,将会试图把字符串转换成数字。这里的"1"就成功的转换成了数字1,于是这个语句就成立了。这就是使用== 操作符返回true的原因。而=== 操作符不允许这么的类型转换,因此会返回false。
那么,这个arr["js"]怎么也能成立呢?这就不是上面的问题了。也就是说,JavaScript实际是允许将字符串作为数字下标的。这在JavaScript中是完全合法的。
对象
1. 对象
对象是面对对象程序设计的基础概念之一,只需看看这个名字就已经懂得了。在我们熟悉的面对对象语言中,例如Java或者C++,都有着类似的对象定义措施。例如,我们想定义一个类,名字叫Person,有两个属性:name和age,另外有一个措施,将显示出这个Person 对象的名字和年龄,那么我们能够用下面的代码实现:
Java:
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void introduction() {
System.out.println("My name is " + this.name + ", my age is " + this.age);
}
public static void main(String[] args) {
Person p = new Person();
p.setName("Tom");
p.setAge(20);
表白代码编程可复制p.introduction();
}
}
复制代码
C++的实现也是类似的,这里不再赘述。
我们先来看一下这个类的定义:首先申明属性,然后定义属性的getter和setter措施,用来
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论