在面向对象的思想中,最核心的概念之一就是类。一个类表示了具有相似性质的一类事物的抽象,通过实例化一个类,可以获得属于该类的一个实例,即对象。
在JavaScript中定义一个类的方法如下:
这里class1既是一个函数也是一个类。可以将它理解为类的构造函数,负责初始化工作。
使用new操作符获得一个类的实例
在前面介绍基本对象时,已经用过new操作符,例如:
表示创建一个日期对象,而Date就是表示日期的类,只是这个类是由JavaScript内部提供的,而不是由用户定义的。
new操作符不仅对内部类有效,对用户定义的类也同样有效,对于上节定义的class1,也可以用new来获取一个实例:
抛开类的概念,从代码的形式上来看,class1就是一个函数,那么是不是所有的函数都可以用new来操作呢?是的,在JavaScript中,函数和类就是一个概念,当对一个函数进行new操作时,就会返回一个对象。如果这个函数中没有初始化类成员,那就会返回一个空的对象。例如:
从运行结果看,执行了hello函数,同时obj也获得了一个对象的引用。当new一个函数时,这个函数就是所代表类的构造函数,其中的代码被看作为了初始化一个对象。用于表示类的函数也称为构造器。
使用方括号([ ])引用对象的属性和方法
在JavaScript中,每个对象可以看作是多个属性(方法)的集合,引用一个属性(方法)很简单,如:
对象名.属性(方法)名
还可以用方括号的形式来引用:
对象名["属性(方法)名"]
注意,这里的方法名和属性名是一个字符串,不是原先点(? )号后面的标识符,例如:
图1显示了执行的结果。
由此可见,上面的代码等价于:
这种引用属性(方法)的方式和数组类似,体现了JavaScript对象就是一组属性(方法)的集合这个性质。
这种用法适合不确定具体要引用哪个属性(方法)的情况,例如:一个对象用于表示用户资料,用一个字符串表示要使用的那个属性,就可以用这种方式来引用:
在这段代码中,使用一个下拉列表框让用户选择查看哪个信息,每个选项的value就表示用户对象的属性名称。这时如果不采用方括号的形式,可使用如下代码来实现:
而使用方括号语法,则只需写为:
方括号语法像一种参数语法,可用一个变量来表示引用对象的哪个属性。如果不采用这种方法,又不想用条件判断,可以使用eval函数:
这里利用eval函数的性质,执行了一段动态生成的代码,并返回了结果。
实际上,在前面讲述document的集合对象时,就有类似方括号的用法,比如引用页面中一个名为“theForm”的表单对象,以前的用法是:
也可以改写为:
forms对象是一个内部对象,和自定义对象不同的是,它还可以用索引来引用其中的一个属性。
动态添加、修改、删除对象的属性和方法
前面介绍了如何引用一个对象的属性和方法,现在介绍如何为一个对象添加、修改或者删除属性和方法。
其他语言中,对象一旦生成,就不可更改,要为一个对象添加、修改成员必须要在对应的类中修改,并重新实例化,程序也必须重新编译。JavaScript提供了灵活的机制来修改对象的行为,可以动态添加、修改、删除属性和方法。例如:先用类Object来创建一个空对象user:
1.添加属性
这时user对象没有任何属性和方法,可以为它动态的添加属性,例如:
通过上述语句,user对象具有了三个属性:name、age和sex。下面输出这三个语句:
由代码运行效果可知,三个属性已经完全属于user对象了。
2.添加方法
添加方法的过程和添加属性类似:
这就为user对象添加了一个方法“alert”,通过执行它,弹出一个对话框显示自己的名字:
图2显示了执行的结果。
3.修改属性和方法
修改一个属性和方法的过程就是用新的属性替换旧的属性,例如:
这样就修改了user对象name属性的值和alert方法,它从显示“my name is”对话框变为了显示“hello”对话框。
4.删除属性和方法
删除一个属性和方法的过程也很简单,就是将其置为undefined:
这样就删除了name属性和alert方法。
在添加、修改或者删除属性时,和引用属性相同,也可以采用方括号([])语法:
使用这种方式还有一个特点,可以使用非标识符字符串作为属性名称,例如标识符中不允许以数字开头或者出现空格,但在方括号([])语法中却可以使用:
需要注意,在使用这种非标识符作为名称的属性时,仍然要用方括号语法来引用:
而不能写为:
事实上,JavaScript中的每个对象都是动态可变的,这给编程带来了灵活性,也和其他语言产生了区别。使用大括号({ })语法创建无类型对象
传统的面向对象语言中,每个对象都会对应到一个类。上一节讲this指针时提到,JavaScript中的对象其实就是属性(方法)的一个集合,并没有严格意义上类的概念。所以它提供了一种简单的方式来创建对象,即大括号({})语法:
通过大括号括住多个属性或方法及其定义(这些属性或方法用逗号隔开),来实现对象的定义,这段代码就直接定义个了具有n个属性或方法的对象,其中属性名和其定义之间用冒号(:)隔开。例如:
第一行定义了一个无类型对象obj,它等价于:
接着定义了一个对象user及其属性和方法。注意,除了最后一个属性(方法)定义,其他的必须以逗号(,)结尾。其实,使用动态增减属性的方法也可以定义一个完全相同的user对象,读者可使用前面介绍的方法实现。
使用这种方式来定义对象,还可以使用字符串作为属性(方法)名,例如:
这就给对象obj定义了一个属性“001”,这并不是一个有效的标识符,所以要引用这个属性必须使用方括号语法:
由此可见,无类型对象提供了一种创建对象的简便方式,它以紧凑和清晰的语法将一个对象体现为一个完整的实体。而且也有利于减少代码的体积,这对JavaScript代码来说尤其重要,减少体积意味着提高了访问速度。
prototype原型对象
prototype对象是实现面向对象的一个重要机制。每个函数(function)其实也是一个对象,它们对应的类是“Function”,但它们身份特殊,每个函数对象都具有一个子对象prototype。即prototype表示了该函数的原型,而函数也是类,prototype就是表示了一个类的成员的集合。当通过new来获取一个类的对象时,prototype对象的成员都会成为实例化对象的成员。
既然prototype是一个对象,可以使用前面两节介绍的方法对其进行动态的修改,这里先给出一个简单的例子:
在JavaScript中定义一个类的方法如下:
function class1(){ //类成员的定义及构造函数 } |
这里class1既是一个函数也是一个类。可以将它理解为类的构造函数,负责初始化工作。
使用new操作符获得一个类的实例
在前面介绍基本对象时,已经用过new操作符,例如:
new Date(); |
表示创建一个日期对象,而Date就是表示日期的类,只是这个类是由JavaScript内部提供的,而不是由用户定义的。
new操作符不仅对内部类有效,对用户定义的类也同样有效,对于上节定义的class1,也可以用new来获取一个实例:
function class1(){ //类成员的定义及构造函数 } var obj1=new class1(); |
抛开类的概念,从代码的形式上来看,class1就是一个函数,那么是不是所有的函数都可以用new来操作呢?是的,在JavaScript中,函数和类就是一个概念,当对一个函数进行new操作时,就会返回一个对象。如果这个函数中没有初始化类成员,那就会返回一个空的对象。例如:
//定义一个hello函数 function hello(){ alert("hello"); } //通过new一个函数获得一个对象 var obj=new hello(); alert(typeof(obj)); |
从运行结果看,执行了hello函数,同时obj也获得了一个对象的引用。当new一个函数时,这个函数就是所代表类的构造函数,其中的代码被看作为了初始化一个对象。用于表示类的函数也称为构造器。
使用方括号([ ])引用对象的属性和方法
在JavaScript中,每个对象可以看作是多个属性(方法)的集合,引用一个属性(方法)很简单,如:
对象名.属性(方法)名
还可以用方括号的形式来引用:
对象名["属性(方法)名"]
注意,这里的方法名和属性名是一个字符串,不是原先点(? )号后面的标识符,例如:
var arr=new Array(); //为数组添加一个元素 arr["push"]("abc"); //获得数组的长度 var len=arr["length"]; //输出数组的长度 alert(len); |
图1 |
图1显示了执行的结果。
由此可见,上面的代码等价于:
var arr=new Array(); //为数组添加一个元素 arr.push("abc"); //获得数组的长度 var len=arr.length; //输出数组的长度 alert(len); |
这种引用属性(方法)的方式和数组类似,体现了JavaScript对象就是一组属性(方法)的集合这个性质。
这种用法适合不确定具体要引用哪个属性(方法)的情况,例如:一个对象用于表示用户资料,用一个字符串表示要使用的那个属性,就可以用这种方式来引用:
<script language="JavaScript" type="text/javascript"> <!-- //定义了一个User类,包括两个成员age和sex,并指定了初始值。 function User(){ this.age=21; this.sex="male"; } //创建user对象 var user=new User(); //根据下拉列表框显示用户的信息 function show(slt){ if(slt.selectedIndex!=0){ alert(user[slt.value]); } } //--> </script> <!--下拉列表框用于选择用户信息--> <select onchange="show(this)"> <option>请选择需要查看的信息:</option> <option value="age">年龄</option> <option value="sex">性别</option> </select> |
在这段代码中,使用一个下拉列表框让用户选择查看哪个信息,每个选项的value就表示用户对象的属性名称。这时如果不采用方括号的形式,可使用如下代码来实现:
function show(slt){ if(slt.selectedIndex!=0){ if(slt.value=="age")alert(user.age); if(slt.value=="sex")alert(user.sex); } } |
而使用方括号语法,则只需写为:
alert(user[slt.value]); |
方括号语法像一种参数语法,可用一个变量来表示引用对象的哪个属性。如果不采用这种方法,又不想用条件判断,可以使用eval函数:
alert(eval("user."+slt.value)); |
这里利用eval函数的性质,执行了一段动态生成的代码,并返回了结果。
实际上,在前面讲述document的集合对象时,就有类似方括号的用法,比如引用页面中一个名为“theForm”的表单对象,以前的用法是:
document.forms["theForm"]; |
也可以改写为:
document.forms.theForm; |
forms对象是一个内部对象,和自定义对象不同的是,它还可以用索引来引用其中的一个属性。
动态添加、修改、删除对象的属性和方法
前面介绍了如何引用一个对象的属性和方法,现在介绍如何为一个对象添加、修改或者删除属性和方法。
其他语言中,对象一旦生成,就不可更改,要为一个对象添加、修改成员必须要在对应的类中修改,并重新实例化,程序也必须重新编译。JavaScript提供了灵活的机制来修改对象的行为,可以动态添加、修改、删除属性和方法。例如:先用类Object来创建一个空对象user:
var user=new Object(); |
1.添加属性
这时user对象没有任何属性和方法,可以为它动态的添加属性,例如:
user.name="jack"; user.age=21; user.sex="male"; |
通过上述语句,user对象具有了三个属性:name、age和sex。下面输出这三个语句:
alert(user.name); alert(user.age); alert(user.sex); |
由代码运行效果可知,三个属性已经完全属于user对象了。
2.添加方法
添加方法的过程和添加属性类似:
user.alert=function(){ alert("my name is:"+this.name); } |
这就为user对象添加了一个方法“alert”,通过执行它,弹出一个对话框显示自己的名字:
user.alert(); |
图2 |
图2显示了执行的结果。
3.修改属性和方法
修改一个属性和方法的过程就是用新的属性替换旧的属性,例如:
user.name="tom"; user.alert=function(){ alert("hello,"+this.name); } |
这样就修改了user对象name属性的值和alert方法,它从显示“my name is”对话框变为了显示“hello”对话框。
4.删除属性和方法
删除一个属性和方法的过程也很简单,就是将其置为undefined:
user.name=undefined; user.alert=undefined; |
这样就删除了name属性和alert方法。
在添加、修改或者删除属性时,和引用属性相同,也可以采用方括号([])语法:
user["name"]="tom"; |
使用这种方式还有一个特点,可以使用非标识符字符串作为属性名称,例如标识符中不允许以数字开头或者出现空格,但在方括号([])语法中却可以使用:
user["my name"]="tom"; |
需要注意,在使用这种非标识符作为名称的属性时,仍然要用方括号语法来引用:
alert(user["my name"]); |
而不能写为:
alert(user.my name); |
事实上,JavaScript中的每个对象都是动态可变的,这给编程带来了灵活性,也和其他语言产生了区别。使用大括号({ })语法创建无类型对象
传统的面向对象语言中,每个对象都会对应到一个类。上一节讲this指针时提到,JavaScript中的对象其实就是属性(方法)的一个集合,并没有严格意义上类的概念。所以它提供了一种简单的方式来创建对象,即大括号({})语法:
{ property1:statement, property2:statement2, …, propertyN:statmentN } |
通过大括号括住多个属性或方法及其定义(这些属性或方法用逗号隔开),来实现对象的定义,这段代码就直接定义个了具有n个属性或方法的对象,其中属性名和其定义之间用冒号(:)隔开。例如:
<script language="JavaScript" type="text/javascript"> <!-- var obj={}; //定义了一个空对象 var user={ name:"jack", //定义了name属性,初始化为jack favoriteColor:["red","green","black","white"],//定义了颜色喜好数组 hello:function(){ //定义了方法hello alert("hello,"+this.name); }, sex:"male" //定义了性别属性sex,初始化为male } //调用user对象的方法hello user.hello(); //--> </script> |
第一行定义了一个无类型对象obj,它等价于:
var obj=new Object(); |
接着定义了一个对象user及其属性和方法。注意,除了最后一个属性(方法)定义,其他的必须以逗号(,)结尾。其实,使用动态增减属性的方法也可以定义一个完全相同的user对象,读者可使用前面介绍的方法实现。
使用这种方式来定义对象,还可以使用字符串作为属性(方法)名,例如:
var obj={"001":"abc"} |
这就给对象obj定义了一个属性“001”,这并不是一个有效的标识符,所以要引用这个属性必须使用方括号语法:
obj["001"]; |
由此可见,无类型对象提供了一种创建对象的简便方式,它以紧凑和清晰的语法将一个对象体现为一个完整的实体。而且也有利于减少代码的体积,这对JavaScript代码来说尤其重要,减少体积意味着提高了访问速度。
prototype原型对象
prototype对象是实现面向对象的一个重要机制。每个函数(function)其实也是一个对象,它们对应的类是“Function”,但它们身份特殊,每个函数对象都具有一个子对象prototype。即prototype表示了该函数的原型,而函数也是类,prototype就是表示了一个类的成员的集合。当通过new来获取一个类的对象时,prototype对象的成员都会成为实例化对象的成员。
既然prototype是一个对象,可以使用前面两节介绍的方法对其进行动态的修改,这里先给出一个简单的例子:
//定义了一个空类 function class1(){ //empty } //对类的prototype对象进行修改,增加方法method class1.prototype.method=function(){ alert("it's a test method"); } //创建类class1的实例 var obj1=new class1(); //调用obj1的方法method obj1.method(); |
图3显示了执行的结果。 |