第六章 对象
The object definition is contained within a single function called a constructor
Requirements of object-oriented languages
Before a language can be called object-oriented, it must provide four basic capabilities to developers:
1. Encapsulation — the capability to store related information, whether data or methods, together
in an object
2. Aggregation — the capability to store one object inside of another object
3. Inheritance — the capability of a class to rely upon another class (or number of classes) for some
of its properties and methods
4. Polymorphism — the capability to write one function or method that works in a variety of different
ways
ECMAScript supports all four of these requirements and so is considered to be object-oriented.
1、对象创建
var oObject = new Object();
var oStringObject = new String();
2、对象销毁
对象不在有引用的时候,垃圾回收器会自动执行并回收资源。
可以将引用赋为空使在下次回收时将该引用所指对象空间回收。
3、动态绑定,后绑定即运行时才知道所要引用的具体对象
4、Types of Objects对象类型
本地对象Native objects
ECMA-262 defines native objects as “any object supplied by an ECMAScript implementation independent of the host environment.”
They include all the following:
Object Function Array String
Boolean Number Date RegExp
Error EvalError RangeError ReferenceError
SyntaxError TypeError URIError
The Array class
var aColors = new Array();
aColors[0] = “red”;
aColors[1] = “green”;
aColors[2] = “blue”;
或者
var aColors = new Array(“red”, “green”, “blue”);
定义数组对象可指定大小:如var aColors = new Array(20);
同时Array对象具有length属性
var aColors = new Array(“red”, “green”, “blue”);
alert(aColors.length); //outputs “3”
并且长度会随着元素的增加自动增长如:
var aColors = new Array(“red”, “green”, “blue”);
alert(aColors.length); //outputs “3”
aColors[25] = “purple”;
aColors(arr.length); //outputs “26”
最大长度:
Arrays can contain a maximum of 4294967295 items, which should be plenty for
almost all programming needs. If you try to add more than that number, an exception
occurs.
另一种定义数组对象的方法:
var aColors = [“red”, “green”, “blue”];
alert(aColors.length); //outputs “3”
aColors[25] = “purple”;
alert(aColors.length); //outputs “26”
重写Object对象的方法
The Array object overrides the toString() and valueOf() methods to return a special string
var aColors = [“red”, “green”, “blue”];
alert(aColors.toString()); //outputs “red,green,blue”
alert(aColors.valueOf()); //outputs “red,green,blue”
以下为Array与String对象之间的互相转换
var arr2 = ["sddf","eeee"];
alert(arr2.toString())
alert(arr2.join(":"))
var str = "sfsfsf:sfeee:ggg";
var arr3 =str.split(":");
for(var i=0;i<arr3.length;i++){
alert(arr3[i]);
}
再看下例:
var str = "ssfjsfk ewkle";
var arr = str.split("");
alert(arr.toString());
我们经常要实现从字符串到字符的转换,一般我们会选用charAt()但在这里显示了另一种方法
与String相类似的两个方法(concat,slice)
var aColors = [“red”, “green”, “blue”];
var aColors2 = arr.concat(“yellow”, “purple”);
alert(aColors2.toString()); //outputs “red,green,blue,yellow,purple”
alert(aColors.toString()); //outputs “red,green,blue”
var aColors = [“red”, “green”, “blue”, “yellow”, “purple”];
var aColors2 = arr.slice(1);
var aColors3 = arr.slice(1, 4);
alert(aColors2.toString()); //outputs “green,blue,yellow,purple”
alert(aColors3.toString()); //outputs “green,blue,yellow”
JS中的Array还可以当作栈来使用,模拟先进后出的特性
var arr = new Array("dfsf","deee","dddde");
var arrCon = arr.concat("eeeee");
alert(arr.toString());
alert(arrCon.toString());
arr.push("ffff"); //入栈,即在数组最后面增加元素
alert(arr.toString());
arr.pop(); //出栈,即从删除最后面一个元素
alert(arr.toString());
arr.shift(); //删除数组最开始的元素
alert(arr.toString());
arr.unshift("uuuuu") //在数组最开始添加一元素
alert(arr.toString());
对数组的排序与反置
var aColors = [“red”, “green”, “blue”, “yellow”];
aColors.sort();//按字符编码顺序排序
alert(aColors.toString()); //outputs “blue,green,red,yellow”
var aColors = [“red”, “green”, “blue”];
aColors.reverse(); // 将数组反过来存放
alert(aColors.toString()); //outputs “blue,green,red”
需要注意的是,数组的排序是先将所有元素转换为字符串,即调用toString方法,再根据字符的编码排序
如下
var aColors = [3, 32, 2, 5]
aColors.sort();
alert(aColors.toString()); //outputs “2,3,32,5”
另一个重要的函数JavaScript中splice函数是从一个数组中移除一个或多个元素,如果必要,在所移除元素的位置上插入新元素,返回所移除的元素。
arrayObj.splice( start, deleteCount, [item1[, item2[, . . . [,itemN]]]])
start是必选项。指定从数组中移除元素的开始位置,这个位置是从 0 开始计算的。
deleteCount是必选项。要移除的元素的个数。
item1, item2,. . .,itemN是可选项。要在所移除元素的位置上插入的新元素。
如:1、删除数组元素
var arr = new Array("dfsf","deee","dddde");
var arr2 = arr.splice(0,2)
alert(arr2.toString()) //返回的数组,即从arr中删除的第0,第一个元素而返回的数组 outputs dfsf,deee
alert(arr.toString()) //数组arr剩余元素的数组 outputs dddde
2、不删除元素,插入元素
var arr= new Array("dfsf","deee","dddde");
var arr2 = arr.splice(1,0,"eee") //因为第二个参数为0,即不删除元素,而是在第一个元素后插入一个元素所以,outputs 为空
alert(arr2.toString()) //outputs 空
alert(arr.toString()) //dfsf,eee,deee,dddde
3、删除元素并插入元素
var arr = new Array("dfsf","deee","dddde");
var arr2 = arr.splice(1,1,"eee")
alert(arr2.toString()) //outputs deee
alert(arr.toString()) //outputs dfsf,eee,dddde
The Date Class
创建Date对象可用三种形式:
dateObj = new Date()
dateObj = new Date(dateVal)
dateObj = new Date(year, month, date[, hours[, minutes[, seconds[,ms]]]])
Date 对象<!--CSS_START--><!-- @import url(../html-vss/msdnie4a.css); --><!--CSS_END-->
dateObj
必选项。要赋值为 Date 对象的变量名。
dateVal
必选项。如果是数字值,dateVal 表示指定日期与 1970 年 1 月 1 日午夜间全球标准时间 的毫秒数。如果是字符串,则 dateVal 按照 parse 方法中的规则进行解析。dateVal 参数也可以是从某些 ActiveX(R) 对象返回的 VT_DATE 值。
year
必选项。完整的年份,比如,1976(而不是 76)。
month
必选项。表示的月份,是从 0 到 11 之间的整数( 1 月至 12 月)。
date
必选项。表示日期,是从 1 到 31 之间的整数。
hours
可选项。 如果提供了 minutes 则必须给出。表示小时,是从 0 到 23 的整数(午夜到 11pm)。
minutes
可选项。 如果提供了 seconds 则必须给出。表示分钟,是从 0 到 59 的整数。
seconds
可选项。 如果提供了 milliseconds 则必须给出。表示秒钟,是从 0 到 59 的整数。
ms
可选项。 表示毫秒,是从 0 到 999 的整数。
示例1:
function DateDemo(){
var d, s = "Today's date is: "; // 声明变量。
d = new Date(); // 创建 Date 对象。
s += (d.getMonth() + 1) + "/"; // 获取月份。
s += d.getDate() + "/"; // 获取日。
s += d.getYear(); // 获取年份。
return(s); // 返回日期。
}
alert(DateDemo());
两个静态方法:parse(),UTC()
parse 方法<!--CSS_START-->@import url(../html-vss/msdnie4a.css);<!--CSS_END-->
解析一个包含日期的字符串,并返回该日期与 1970 年 1 月 1 日午夜之间所间隔的毫秒数。
Date.parse(dateVal)
其中必选项 dateVal 是一个包含以诸如 "Jan 5, 1996 08:47:00" 的格式表示的日期的字符串,或者是一个从 ActiveX(R) 对象或其他对象中获取的 VT_DATE 值。
说明
parse 方法返回一个整数值,这个整数表示 dateVal 中所包含的日期与 1970 年 1 月 1 日午夜之间相间隔的毫秒数。
parse 方法是 Date 对象的一个静态方法。正因为它是一个静态方法,它是通过下面例子中所示的方法被调用的,而不是作为一个已创建 Date 对象的一个方法被调用。
var datestring = "November 1, 1997 10:15 AM";
Date.parse(datestring)
下面这些规则决定了 parse 方法能够成功地解析那些字符串:
1、短日期可以使用“/”或“-”作为日期分隔符,但是必须用月/日/年的格式来表示,例如"7/20/96"。
2、以 "July 10 1995" 形式表示的长日期中的年、月、日可以按任何顺序排列,年份值可以用 2 位数字表示也可以用 4 位数字表示。如果使用 2 位数字来表示年份,那么该年份必须大于或等于 70。
3、括号中的任何文本都被视为注释。这些括号可以嵌套使用。
4、逗号和空格被视为分隔符。允许使用多个分隔符。
5、月和日的名称必须具有两个或两个以上的字符。如果两个字符所组成的名称不是独一无二的,那么该名称就被解析成最后一个符合条件的月或日。例如,"Ju" 被解释为七月而不是六月。
6、在所提供的日期中,如果所指定的星期几的值与按照该日期中剩余部分所确定的星期几的值不符合,那么该指定值就会被忽略。例如,尽管 1996 年 11 月 9 日实际上是星期五,"Tuesday November 9 1996" 也还是可以被接受并进行解析的。但是结果 Date 对象中包含的是 "Friday November 9 1996"。
7、JScript 处理所有的标准时区,以及全球标准时间 (UTC) 和格林威治标准时间 (GMT)。
小时、分钟、和秒钟之间用冒号分隔,尽管不是这三项都需要指明。"10:"、"10:11"、和 "10:11:12" 都是有效的。
8、如果使用 24 小时计时的时钟,那么为中午 12 点之后的时间指定 "PM" 是错误的。例如 "23:15 PM" 就是错误的。
9、包含无效日期的字符串是错误的。例如,一个包含有两个年份或两个月份的字符串就是错误的。
示例
下面这个例子说明了 parse 方法的用法:
function GetTimeTest(testdate){
var s, t; // 声明变量。
var MinMilli = 1000 * 60; // 初始化变量。
var HrMilli = MinMilli * 60;
var DyMilli = HrMilli * 24;
t = Date.parse(testdate); // 解析 testdate。
s = "There are " // 创建返回的字符串。
s += Math.round(Math.abs(t / DyMilli)) + " days "
s += "between " + testdate + " and 1/1/70";
return(s); // 返回结果。
}
toString()和valueOf()方法返回不同的值
toString()返回的是日期的字符串形式而valueOf()返回的是与1970.1.1相差的毫秒数
Date类还有其它一些方法,可见JS参考
5、内置对象(固有对象)
Global对象和Math对象
Global目的是把所有全局方法集中在一个对象中。Global 对象从不直接使用,并且不能用 new 运算符创建。它在 Scripting 引擎被初始化时创建,并立即使其方法和属性可用
属性
Infinity 属性 | NaN 属性
属性并不止上面两个,包括本地对象的构造在内都是它的属性,如String,Number,Date等
成员方法有:
escape 方法 | eval 方法 | isFinite 方法 | isNaN 方法 | parseFloat 方法 | parseInt 方法 | unescape 方法
有关escape方法可参见另两篇文章:
http://blog.csdn.net/luweifeng1983/archive/2008/12/16/3530432.aspx
http://blog.csdn.net/luweifeng1983/archive/2008/12/16/3530422.aspx
Math对象
方法:
alert(Math.ceil(25.5)); //outputs “26” 返回大于参数的最小整数
alert(Math.round(25.5)); //outputs “26”
alert(Math.floor(25.5)); //outputs “25” 返回小于参数的最大整数
6、主机对象
All BOM and DOM objects are considered to be host objects and are discussed later in the book.
7、创建类和对象的发展
创建一个对象
var oTempCar = new Object;
oTempCar.color ="red";
oTempCar.doors = 5;
oTempCar.mpg = 23;
oTempCar.showColor = function(){
alert(this.color)
};
相对于上面来说,如果我要创建多个对象呢?
工厂模式:
function createCar(){
var oTempCar = new Object;
oTempCar.color ="red";
oTempCar.doors = 5;
oTempCar.mpg = 23;
oTempCar.showColor = function(){
alert(this.color)
};
return oTempCar;
}
进一步优化:
function showColor(){
alert(this.color)
}
function createCar(sColor,iDoor,iMpg){
var oTempCar = new Object;
oTempCar.color =sColor;
oTempCar.doors = iDoor;
oTempCar.mpg = iMpg;
oTempCar.showColor = showColor;
return oTempCar;
}
var oCar1 = createCar("red",4,23);
可以看到工厂模式中使用一个函数返回对象,按JS来说,函数也是对象,在这里createCar方法并没有体现对象的概念,所以进一步提出:
构造模式
function Car(sColor,iDoor,iMpg){
this.color = sColor;
this.doors = iDoor;
this.mpg = iMpg;
this.showColor = function(){
alert(this.color)
};
}
var oCar1 = new Car("red",4,23);
原型模式
function Car(){
}
Car.prototype.color = "red";
Car.prototype.doors = 5;
Car.prototype.mpg = 4;
Car.prototype.showColor = function(){
alert(this.color);
};
var oCar1 = new Car();
事实上原型模式对增加成员方法更实用,所以构造类及创建对象最好的方法是把构造模式与原型模式结合起来
即在构造函数中定义属性,再使用原型模式添加成员方法。
function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array(“Mike”, “Sue”);
}
Car.prototype.showColor = function () {
alert(this.color);
};
var oCar1 = new Car(“red”, 4, 23);
var oCar2 = new Car(“blue”, 3, 25);
oCar1.drivers.push(“Matt”);
alert(oCar1.drivers); //outputs “Mike,Sue,Matt”
alert(oCar2.drivers); //outputs “Mike,Sue”
注意了,可以利用prototype属性为你创建的对象或本地对象添加或重写方法
http://blog.csdn.net/luweifeng1983/archive/2009/02/20/3915189.aspx
http://blog.csdn.net/luweifeng1983/archive/2009/02/20/3915284.aspx