对象Object用于描述客观世界存在的特定实体。对象包含两个要素,属性和方法。属性是用来描述对象特性的一组数据,即若干变量;方法是用来操作对象的若干动作,也就是函数。
JavaScript中,对象就是属性与函数的集合。属性是作为对象成员的变量,表明对象的状态;方法是作为对象成员的函数,表明对象所具有的行为。通过访问或设置对象的属性,并且调用对象的方法,就可以对对象进行各种操作,从而获得需要的功能。
JavaScript是一种基于对象的编程语言,也支持面向对象程序设计。面向对象程序语言有3个基本特征:封装性、继承性和多态性。封装性指可以将属性和方法存储到对象中;继承性是指一个对象能够继承另一个对象的属性和方法;多态性是指一个对象可以是多个对象类的实例。JavaScript中,有3种对象:内置对象、浏览器对象(或宿主对象)和自定义对象。内置对象和浏览器对象合称预定义对象。
1. 类class:
为了描述一组具有相似特性和行为的对象,引入类的概念。类(或称对象类)是对具有相同属性和方法的一组对象的抽象描述,用作对象创建的模板。
1)定义对象类:
要定义对象类,必须定义构造函数,构造函数一般与类名相同。示例:
function Person(name,gender)
{
this.name = name; //定义属性
this.gender = gender; //定义属性
this.introduceSelf = function()
{
document.writeln("My name is"+this.name+","+this.gender);
}
}
形式上,构造函数与普通函数类似,不同之处是内部一般不使用return语句,并且要使用this关键字引用新创建的对象。
定义了类之后,就可以使用new创建类的实例(instance),即对象(或称对象实例)。在对象编程中,对象、对象实例和类实例是相同的概念,都是指对象Object。示例:
var p1 = new Person("Tom","male");
对构造函数的调用必须有new关键字。执行构造函数,相当于为新建的对象定义属性和方法。
2)New运算符:
JavaScript中,new运算符的完整语法格式为:
new constructor(arg1,arg2,...,argn);
其中,constructor是新建对象的构造函数。在JavaScript中,类就是构造函数,而类名就是构造函数名。
任何对象都有constructor属性,引用创建该对象的构造函数对象,而函数对象的toString()方法将返回函数代码。Date、String、Array等预定义对象类名也是对应构造函数的引用,但toString()方法不会返回这些构造函数的内部代码。
3)Instanceof运算符:
Instanceof用于判断对象是否是指定类的一个实例,语法格式为:
object instanceof class
如果object是class的一个实例,则返回true,否则返回false。
4)类对象的prototype属性:
类对象的prototype属性是对一个对象的引用,该对象称为类实例对象的原型对象。默认情况下,原型对象是一个object对象。
原型对象的主要用途是为类的实例对象提供共享的方法和属性,从而避免为每个对象定义代码相同的方法或值相同的属性。因此,通过实例对象可以访问的属性和方法分为以下两类:一类是实例对象自定义的属性和方法,另一类是来自于原型对象的属性和方法(或称原型属性和原型方法)。示例:在Person的构造函数中这样定义方法。
Person.prototype.introduceSelf = function()
{
Document.writeln("My name"+this.name+","+this.gender);
}
为了使同一个类的每个实例对象能够共享相同的方法,一般按两步定义对象:①在构造函数中定义对象的属性;②在原型对象中为对象定义共享的方法。
2.继承:
JavaScript的继承机制是通过原型链来实现的。
1)定义子类:
继承,是指一个对象(如A)的属性和方法来自另一个对象(如B)。此时,称定义对象对象A的类为子类,定义对象B的类为父类。
在JavaScript中,为子类指定父类的方法是将父类的实例对象赋值给子类的prototype属性:
A.prototype = new B(...);
示例:通过继承Person类,定义子类Student,子类多一个属性grade。
function Person(name,gender){
this.name = name; //定义属性
this.gender = gender; //定义属性
Person.prototype.introduceSelf = function()
{
document.writeln("My name"+this.name+","+this.gender);
}
function student(name,gender,grade)
{
Person.call(this.name,gender); //子类中重新定义父类的属性
this.grade = grade;
}
Student.prototype= new Person(); //将类Person定义为类Student的父类
var s=new Student("Tom","male",80);
s.introduceSelf(); //调用继承的方法
Student.prototype.introduceSelf=function() //重定义继承的方法
{
document.writeln("My name"+this.name+","+this.gender+","+this.grade);
}
s.introduceSelf(); //调用重定义的方法
if (s instanceof Person) document.writeln(s.name+"is Person");
if (s instanceof Student) document.writeln(s.name+"is Student");
}
2)重定义继承的属性和方法:
在定义子类时,也可以重新定义从父类继承而来的属性和方法。
①重定义继承的属性:
若要重定义继承的属性,则在子类构造函数中定义与父类属性同名的属性。
示例中Student构造函数中调用Person.call(this,name,gender)的效果,相当于在类Student的构造函数中执行出现于Person构造函数中的以下两条语句:
this.name = name; //定义属性
this.gender = gender; //定义属性
从而在Student类中重定义了来自父类Person的name和gender属性。
②重定义继承的方法:
若要重定义继承的方法,则为原型对象定义与父类方法同名的方法。
示例中,为Student对象的原型对象定义了以下方法:
Student.prototype.introduceSelf=function() //重定义继承的方法
{
document.writeln("My name"+this.name+","+this.gender+","+this.grade);
}
从而在Student类中重定义了来自于父类Person的方法。
3.对象创建:
定义了类之后,就可以创建类的对象。运算符new用以创建对象,格式为:
引用变量=new 对象类();
将新建的对象赋值给一个变量之后,就可以通过这个变量访问对象的属性和方法。此时,把这个变量称为引用变量或对象变量。
4.原始值与引用:
在JavaScript中,变量存储的值可以分为以下两种:
①原始值:直接存储在变量中的简单数据,如数值、布尔值和字符串等。
②引用值:变量不能直接存储对象,只能存储对象的指针(或称引用),该指针是对象在内存中的存储地址。此时,将存储对象引用值的变量称为引用变量。
由于引用变量是对一个对象的引用,因此当将引用变量赋值给另一个变量时,不会创建新对象,而是使这两个变量的引用(或指向)同一个对象。
5.对象删除:
JavaScript具有无用对象的自动回收功能,即当一个对象没有任何变量引用时,该对象将自动删除。因此,删除对象的方法是将引用该对象的所有变量赋值为null,形如:
引用变量 = null;
由于一个引用变量在超出其作用域范围时,JavaScript会自动将该变量赋值为null,因此在编写小的JavaScript程序时,一般不必关心无用对象的删除问题。
6.字面量对象:
字面量对象,是指在程序代码中直接书写的对象,使用一对大括号括起来一个或多个用逗号分隔的属性说明,而每个属性声明写成"属性名:属性值"对。示例:
var person = {
name:"Tom",
gender:"male"
};
7.定义属性:
无论自定义对象,还是预定义对象,都可以包含自定义属性,即可以为现有对象定义新的属性。定义属性的方法是直接为对象的新属性赋值,格式为:
obj.new_attr = some_value;
对象的自定义属性与其他属性的使用方法基本相同,但可以用delete删除对象的自定义属性:
delete obj.new_attr;
任何对象都有hasOwnProperty(proName)方法,用于测试对象是否含有指定名称的属性。
8.列举对象的自定义属性:
对象相当于一组属性名至属性值的映射,类似遍历数组,使用for...in语句可以列举对象的自定义属性。示例:
for (var proName in Person)
{
document.writeln(proName+":"+person[proName]);
}
9.定义方法:
JavaScript中,由于任何函数都是Function对象,因此为对象定义新方法的简单办法就是将一个函数的对象赋值给对象的新属性,如同定义新属性。格式为:
obj.new_method=fun_obj;
示例:
person.sayhi= function(msg)
{
Document.writeln(msg);
}
10.关键字this:
JavaScript中,任何方法都必须通过某种对象调用才能执行,即方法必须执行在某个对象之上。
不同的对象会有相同的方法,而在编程时需要指定是通过哪个对象调用这个方法。JavaScript提供了关键字this,引用当前对象,即调用该方法的对象。