3、面向对象
3.1面向对象
属性的无序集合,每个属性存放一个原始值、对象和函数
通用的定义基于代码的名词表示
ecmascript 并没有正式的类,相反,ecmascript-262把对象定义描述为对象的配方。
对象定义存放在一个函数中--构造函数。构造函数不是特殊函数,它只是用于创建对象的常规函数。
面向对象需要向开发者提供四种基本能力:
1、封装--把相关信息存储在对象中的能力。
2、聚集--把对象存储在另一个对象内的能力。
3、继承--由另一个类得来累的属性和方法的能力。
4、多态--编写能以多种方法运行的函数或方法的能力。
3.1.2 对象的构成
属性+方法
3.2 对象的应用
3.2.1 声明和实例化
var oObject = new Object();
var oStringObject = new String();
var oObject = new Object;
var oStringObject = new String;
3.2.2 对象引用
在ECMAScript中,不能访问对象的物理表示,只能访问对象的引用。每次创建对象,存储的都是对象的引用,而不是对象本身。
3.2.3 对象删除
ECMAScript 有无用存储单元收集程序。函数执行完毕,所有没有对对象引用时,都被废除。
强制废除对象,null
var oObject = new Object;
oObject = null;
则oObject 被废除,但并没有被销毁。当下次再运行无用存储单元收集程序时,被销毁。
每当用完对象,对其废除,是个好习惯。
废除对象的所有引用时要当心。如果一个对象有两个或更多个引用,则要正确废除该对象,必须将所有引用都设置为null。
3.2.4 早绑定和晚绑定
所谓绑定 是指 把对象的接口与对象实例结合在一起的方法。
早绑定:在实例化对象之前定义它的特性和方法,这样编译器和解释程序能提前转换机器代码。
ECMAScript不是强类型,不支持早绑定。
晚绑定:指的是 编译器或解释程序之前,不知道对象的类型。
晚绑定,无需检查对象的类型,只需检查对象是否支持特性和方法即可。
3.3 对象的类型
可以创建和使用的对象有三种。
3.3.1本地对象
独立于宿主环境的ECMAScript实现提供的对象。就是ecma-262定义的类。
Object Function Array String Boolean Number Data RegExp Error
EvalError RangError ReferenceError SyntanError TypeError URIError
1、Array类
var aValues = new Array();
var aValues = new Array(20);
var aColors = new Array();
aColors[0] = "red";
aColors[1] = "green";
aColors[2] = "blue";
var aColors = new Array("red","green","blue");
二者都可以通过位置访问。
alert(aColor[1]); // green
length属性,可以得到数组的大小。
增加一个值
var aColors = new Array("red","green","blue");
aColors[3] = "purple";
alert(aColors.length); //4
aColors[25] = "purple";
alert(aColors.length); //26
字面量定义:
var aColors = ["red","green","blue"];
aColors["25"] = "purple";
alert(aColors.length);
toString(), valueOf()方法返回的是字符串。对于 aColors 返回"red,grean,blue"字符串。
join()连接字符串,用特别的字符。如:
var aColors = ["red","green","blue"];
alert(aColors.join("-spring-")); //"red-spring-green-spring-blue"
String的split()方法可以只有一个参数,可以把字符串转化成数组。
var sColors = "red,green,blue";
var aColors = sColors.split(",");
Array 有两个String类具有的方法 concat()和slice()方法。concat()将参数附加在数组末尾,返回值是新的数组。
var aColors = ["red","green","blue"];
var aColors2= aColors.concat("yellow","purple");
alert(aClors.toString());
alert(aColors2.toString());
slice方法也和String的Slice方法类似。
var aColors = ["red","green","blue","yellow","purple"];
var aColors2 = arr.slice(1); // green,blue,yellow,purple
var aColors3 = arr.slice(1,4); //green,blue,yellow
一些方法可以模拟栈,后进先出,限制了插入删除项的位置,在栈顶。
可以通过push和pop类模拟。
var stack = new Array;
stack.push("green");
stack.push("yellow");
alert(stack.toString()); //red,green,yellow
var vItem = stack.push(stack.pop());
alert(vItem); //yellow
alert(stack.toString()); //red,green
push可以传递多个参数。
Array 还提供操作第一项的方法。shift()删除数组的第一项,并将其作为值返回。
另一个unshift()方法,它把一个项放在数组的第一个位置,然后其余项向下移动一个位置。
var aColors = ["red","green","yellow"];
var vItem = aColors.shift();
alert(aColor.toString()); //green,yellow
alert(vItem); //red
aColors.unshift("black");
alert(aColors.toString()); //black,green,yellow
通过调用shift和push可以模拟队列。queue。
enqueue 入队。dequeue 出队。
sort()将数组值按升序排列。要保证值为字母。对于数字 会有 2,3,32,5这种情况。
splice() 将数据项插入数组的中部。 变体:
删除--arr.splice(0,2);删除arr的前两项。
替换而不删除--arr.splice(2,0,"red","green");将位置2处插入red,green。
替换并删除--arr.splice(2,1,"red","green");删除数组位置2处的项,并在2处插入red,green
2.Data类
var d = new Date();
第一种方法 只声明距离1970.1.1的时间毫秒数
var d = new Date(0);
parse() UTC() ;parse()可以接受日期格式,
mm/dd/yyyy 6/13/2004
mmmm dd,yyyy January 12,2004
var d = new Date(Date.parse("May 25,2004"));可以为2004,5,25创建Date对象,使用parse()方法获得它的毫秒数表示,
然后将该值传递给Date构造函数。如果parse()的参数不能转化成日期,则返回NaN.
UTC()方法也返回日期的毫秒数,年月日,时分秒毫秒格式,年月必须,其他可以选。 11代表12月。
2004年2月5号的毫秒数为
var d = new Date(Date.UTC(2004,1,5));
小时采用24小时制,2004年2月5号下午1:05
var d = new Date(Date.UTC(2004,1,5,13,5));
创建日期的第二种方法是直接声明UTC()接受的参数:
var d = new Date(2004,1,5);
valueOf()返回毫秒数;toString()返回特定的字符串,采用人们可以读懂的格式。
Date的方法列表
3.3.2 内置对象
ECMA-262只定义了两个内置对象 Global和Math。
1、Global对象
Global对象是最特别的对象,因为它根本不存在。在ECMA中,不存在对立函数,所有函数都是对象的方法。
encodeURI()和encodeURIComponent()用于编码产地给浏览器的URI。用这两个方法编码URI 是用专门的UTF-8编码替换所有非有效的字符。
encodeURI()用于处理完整的URI。encodeURIComponent()则处理URI片段。
区别在于encodeURI()方法不对URI中的特殊字符进行编码,如冒号、前斜杠、问好、英镑号
而encodeURIComponent()对它发现的所有非标准字符编码。
还有两个方法用于解码编码过的URI,即decodeURI()方法和decodeURIComponent().
eval(),象ECMAScript的解释程序。
2、Math对象
Math对象的属性
Math对象的方法:
min() max()用于判断一组数中的最大最小值。
var iMax = Math.max(3,54,32,16);//54
var iMin = Math.min(3,54,32,16);//3
另一个方法返回数字的绝对值。
var iNegOne = Math.abs(-1); //1
小数取舍。ceil()向上进位。floor()向下舍。round()五舍六入,以5为界
另一组与指数相关。exp(),用于把Math.E升到指定的幂;log()用于返回指定数字的自然对数;
pow()用于把指定的数字升到指定的幂;sqrt平方根。
var iNum = Math.log(Math.exp(10));
var iNum = Math.pow(2,10);//2的10次幂。
random()返回0到1的小数,常用于随机数。
number = Math.floor(Math.random()*total_number+fristNum);
2-9随机数
var iNum = Math.floor(Math.random()*9+2);
3.3.3宿主对象。BOM DOM对象。
3.4作用域
3.4.1 公用、受保护和私有作用域
ECMAScript只有一种作用域--公用作用域。自己制定的规则,在属性和方法前加下
划线,区别公用私用。
obj.__color__ = "red";
只是标记,并不改变公用属性的事实。
3.4.2 静态作用域并非静态的
严格的说ECMAScript并没有静态作用域。不过,它可以给构造函数提供属性和方法
。
例如:
function sayHi(){
alert("hi");
}
sayHi.alternate = function(){
sayHi();
sayHi.alternate();
}
3.4.3 关键字 this
它用在对象的方法中。关键字总是指向调用该方法的对象。
var oCar = new Object;
oCar.color = "red";
oCar.showColor = function(){
alter(this.color); //red
};
等价于:
var oCar = new Object;
oCar.color = "red";
oCar.showColor = function(){
alter(oCar.color); //red
};
如果不用对象或this关键字引用变量,ECMAScript就会把它看成局部变量或全局变
量。然后函数将查找名为color的局部变量或全局变量,找不到就警告null。
3.5 定义类或对象
使用预定义对象的能力知识面向对象语言能力的一部分,它真正的强大之处在于能
够创建自己专用的类和对象。
3.5.1工厂方式
因为对象的属性可以再创建对象后动态定义,
var oCar = new Object;
oCar.color = "red";
oCar.doors = 4;
oCar.mpg = 23;
oCar.showColor = function(){
alert(this.color);
};
但是不只创造一个对象car。开发者创造了能创建并返回特定类型的对象的工厂函数
。
function createCar(){
var oTempCar = new Object;
oTempCar.color = "red";
oTempCar.door = 4;
oTempCar.mpg = 23;
oTempCar.showColor = function(){
alert(this.color);
};
return oTempCar;
}
var oCar1 = createCar();
var oCar2 = createCar();
也可以传递参数,例如
function createCar(sColor,iDoors,iMpg){
var oTempCar = new Object;
oTempCar.color = sColor;
oTempCar.door = iDoors;
oTempCar.mpg = iMpg;
oTempCar.showColor = function(){
alert(this.color);
}
return oTempCar;
}
var oCar1 = createCar("red",4,23);
var oCar2 = createCar("blue",3,25);
oCar1.showColor(); //red
oCar2.showColor(); //blue
每次都创建函数showColor(),意味着每个函数都创建自己的函数,然而实际上每个
对象都共享了同一个函数。
function(){
alert(this.color);
}
function createCar(sColor,iDoors,iMpg){
var oTempCar = new Object;
oTempCar.color = sColor;
oTempCar.door = iDoors;
oTempCar.mpg = iMpg;
oTempCar.showColor = showColor;
return oTempCar;
}
var oCar1 = createCar("red",4,23);
var oCar2 = createCar("blue",3,25);
oCar1.showColor(); //red
oCar2.showColor(); //blue
3.5.2 构造函数方式
function Car(sColor,iDoors,iMpg){
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.showColor = function(){
alert(this.color);
};
}
var oCar1 = new Car("red",4,23);
var oCar2 = new Car("blue",3,25);
使用new运算符时调用构造函数时,在执行第一行代码前创建一个对象,只有this才
能访问该对象。然后直接赋予this属性,默认情况下构造函数返回的是this对象。
3.5.3 原型方式
利用了prototype的属性,可以把它看成创建新对象所依赖的原型。
function() Car(){
}
Car.prototype.color = "red";
Car.prototype.doors = 4;
Car.prototype.mpg = 23;
Car.prototype.showColor = function(){
alert(this.color);
};
var oCar1 = new Car();
var oCar2 = new Car();
alert(oCar1 instanceof Car); //true
有两个问题
1、构造函数没有参数。
2、属性指向的是对象时,而不是函数时。
function() Car(){
}
Car.prototype.color = "red";
Car.prototype.doors = 4;
Car.prototype.mpg = 23;
Car.prototype.drivers = new Array("Mike","Sue");
Car.prototype.showColor = function(){
alert(this.color);
};
var oCar1 = new Car();
var oCar2 = new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers); // Mike,Sue,Matt
alert(oCar1.drivers); // Mike,Sue,Matt
3.5.4 混合的构造函数/原型方式
这种方法概念:用构造函数定义对象的所有非函数属性,用原型方式定义对象的函
数属性。
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); //Mike,Sue,Matt
alert(oCar1.drivers); //Mike,Sue
3.6 修改对象
在ECMAScript中,可以修改String、Array、Number或任意一种对象的的行为。
3.6.3 极晚绑定
实例化对象后再绑定方法。
var o = new Object;
Object.prototype.sayHi = function(){
alert("hi");
};
o.sayHi();
by simpman