《JavaScript高级程序设计》读书笔记二对象基础

 对象基础

一、ECMA-262面向对象术语

1.对象(object):属性的无序集合,每个属性存放一个原始值、对象或函数

2.类是对象的配方(对象定义),不仅要定义对象的接口(interface)(开发者访问的属性和

方法),还要定义对象的内部工作(使属性和方法发挥作用的代码)。

3.编译器和解释程序都根据类的说明构建对象,生成的对象叫做类的实例(instance)其

过程叫实例化(instantiation).对象定义存放在构造函数——用于创建对象的常规函数。

4.面向对象语言的要求

1)封装——把相关的信息(无论数据或方法)存储在对象中的能力。

2)聚集——把一个对象存储在另一个对象内的能力

3)继承——由另一个类(或多个类)得来类的属性和方法的能力。

4)多态——编写能以多种方式运行的函数或方法的能力。

5.对象由特性(attribute)构成,特性可以是原始值,也可以是引用值。如果特性存放的

是函数,它将被看作对象的方法(method),否则该特性被看做属性(property)。

二、对象应用

1.声明和实例化

var oObject=new Object() 

var oObject=new Object   //若构造函数无参数,括号可以省略

2.对象废除(dereference)

oObject=null //把对象的所有引用都设置为null,可以强制性的废除对象。

3.所有变量都采用晚绑定(late binding)方法,与C#,Java等早绑定(early binding)区别

三、本地对象

本地对象(native object):独立于宿主环境的ECMAScript实现提供的对象。

本地对象实际上就是ECMA-262定义的类(引用类型)。它们包括:

Object           Function               Array              String               Boolean

Number         Date                     RegExp           Error                EvalError

RangeError    ReferenceError     SyntaxError     TypeError        URLError

1.Array类

var aValues1=new Array(), aValues2=new Array(20); //20是数组大小

var aColors=new Array();

aColors[0]="red", aColors[1]="green", aColors[2]="blue";//动态添加数组项

var aColors=new Array("red","green","blue"); //可参数声明值

alert(aColors[1]);  //outputs "green"

aColors[9]="purple";

//数组可以根据需要来增大或减小,其中3到8的位置都添上值null

alert(aColors.length); //outputs "10"

var aColors=["red","green","blue"];  //字面量定义Array,跟传统定义相同

alert(aColors.toString());  //outputs "red,green,blue"

alert(aColors.valueOf());  //outputs "red,green,blue"

alert(aColors.toLocaleString());  //outputs "red,green,blue" 组合每一项的toLocaleString()

alert(aColors.join("-")); //outputs "red-green-blue" join()可采用任何字符串做分隔符

var sColors="red,green,blue";

var aColors=sColors.split(","); //split()方法把字符串转换为Array对象,参数为分隔符。

//split()如果把空字符串声明为分隔符,那返回的数组中每个项是字符串的字符。

var aColors2=aColor.concat("yellow","purple");//equal "red,green,blue,yellow,purple"

var aColors3=aColors2.slice(1,3);//equal "green,blue" slice()只返回后一个位置之前的项

var vItem=aColors.pop(); //equal "blue"

alert(aColors.valueOf()); //outputs "red,green"

aColors.push("yellow");

alert(aColors.toString()); //outputs "red,green,yellow"

var vItem=aColors.shift(); //equal "red"    shift()用来移除数组的第一项

aColors.unShift("black"); //unShift()把一个项放在数组的第一项,其他依次后移

alert(aColors.toString()); //outputs "black,green,yellow"

//通过pop()和push()方法,使Array具有堆栈(stack)行为,后进先出(LIFO)结构。

//通过shift()和push()方法,使Array具有队列(queue)行为,后进后出(LILO)结。

aColors.reverse();  //reverse()方法用来颠倒数组项的顺序

alert(aColors.toString()); //outputs "yellow,green,black"

var afigure=[3,32,2,5];

afigure.sort();  //sort()方法用来根据数组各项的toString()值对数组项进行升序排序

alert(afigure.toString()); //outputs "2,3,32,5"

afigure.splice(0,2);//删除数组afigure的前两项

afigure.splice(2,0,4,6);//在位置2处插入4和6

afigure.splice(2,1,7,8);//删除在位置2的项,在位置2处插入7和8

2.Date类

ECMAScript把日期存储为距离UTC时间1970年1月1日凌晨12点的毫秒数。

var d=new Date();

var d=new Date(0);//设置日期和时间的值方式一,只声明距离上面的UTC的毫秒数

var d=new Date(Date.parse("May 25,2004"));/*parse()方法可将字符串转换成毫秒数

parse()除了mmmm dd,yyyy格式外,还支持mm/dd/yyyy等其他日期格式字符串

若pasre()方法的字符串不能转换成日期,整个函数返回NaN */

var d=new Date(Date.UTC(2004,1,5));/*UTC()方法参数为日期中的年和月(必须声明)

及其他可选参数:日、小时、分、秒和毫秒。注意月份值是0-11*/

var d=new Date(2004,1,4,13,15,32);//设置Date值方式二,直接声明UTC()可用的参数

alert(d.toString());//outputs "Wed Fed 4 13:15:32 UTC+0800 2004" 返回实现特定字符串

alert(d.valueOf()): //outputs "1075871732000"  返回日期的毫秒表示

alert(d.toDateString()); //outputs "Web Fed 4 2004" 返回实现特定格式的日期部分

alert(d.toTimeString()); //outputs "13:15:32 UTC+0800" 返回实现特定格式的时间部分

alert(d.toLocaleString()); //outputs "2004年2月4日 星期三 13:15:32" 区域特定格式

alert(d.toLocaleDateString()); //outputs "2004年2月4日 星期三" 区域特定日期部分

alert(d.toLocaleTimeString()); //outputs "13:15:32" 区域特定时间部分

alert(d.UTCString()); //outputs "web, 4 Feb 2004 05:15:32 UTC" 返回世界标准时间

alert(d.getTimezoneOffset()); //outputs "-480" 返回当前时区比UTC提前或落后的分种数

var d1=new Date(2004,0,1);

var d2=new Date(2004,6,1);

var bSupportsDaylightSavingTime=d1.getTimezoneOffset()!=d2.getTimezoneOffset();

//比较一年中春夏时间的时区偏移量,如果分钟不等,则该时区使用的是夏令时

d.setTime(1075999992000);  //设置日期的毫秒表示

alert(d.toLocaleString());  //outputs "2004年2月6日 星期五 0:53:12"

alert(d.getTime()); //outputs "1075999992000" 返回日期的毫秒表示

d.setFullYear(2008); //设置日期的年份,参数必须是四位数字的年份值

alert(d.getFullYear()); //outputs "2008" 返回用四位数值表示的年份值

d.setUTCFullYear(2009); //设置UTC日期的年份

alert(d.getUTCFullYear()); //outputs "2009" 返回UTC日期的年份

其他对日期其他部分的获取和设置跟年份获取和设置大同小异。

月     getMonth()    getUTCMonth()       setMonth(month)       setUTCMont(month)

日     getDate()       getUTCDate()          setDate(date)             setUTCDate(date)

星期 getDay()        getUTCDay()           setDay(day)              setUTCDay(day)

小时 getHours()     getUTCHours()         setHours(hours)        setUTCHours(hours)

分钟 getMinutes()  getUTCMinutes()      setMinutes(minutes)   setUTCMinutes(minutes)

秒     getSeconds()  getUTCSeconds()     setSeconds(seconds)   setUTCSeconds(seconds)

毫秒 getMilliseconds() getUTCMilliseconds() setM...ds(Milliseconds) setUT...ds(Mil...ds)

四、内置对象

内置对象(built-in object)是由ECMAScript实现提供的、独立于宿主环境的所有对象,

在ECMAScript程序开始执行时出现。意味开发者不用实例化它们,它们已经被实例

化了。ECMA-262只定义两个内置对象,Global和Math,内置对象也都是本地对象。

1.Global对象

1)属性

如一些特殊值undefined、NaN、Infinity等,此外所有本地对象的构造函数也都是

Global对象的属性:Object、Array、Function、Boolean、String、Number、Date、

RegExp、Error、EvalError、RangeError、RefrenceError、SytaxError、TypeError、

URIError等。

2)方法

Global是很特别的对象,实际上他不存在,如:var pointer=Global 将报错,貌似独立

存在的函数,例如isNaN()、isFinite()、parseInt()、parseFloat()等等都是Global的方法

原因是在ECMAScript中,不存在独立的函数,所有函数必须是某个对象的方法。

encodeURI()和encodeURIComponent()用来编码传递给浏览器的URI(统一资源标识符)

encodeURI()用来处理完整的URI,而不对URI中的特殊字符进行编码,如冒号、前斜

杠、问号和英镑符号等。

encodeURIComponent()用于处理URI的一个片段,对它发现的所有非标准字符进行编码

var sUri="httptest://www.163.com/A B.htm#ha&ha"

alert(encodeURI(sUri));  //outputs "httptest://www.163.com/A%20B.htm#ha&ha"

alert(encodeURIComponent(sUri));

//outputs "httptest%3A%2F%2Fwww.163.com%2FA%20B.htm%23ha%26ha"

decodeURI()和decodeURIComponent()用于对编码的字符进行解码。区分与上面相同

以上四个URI方法可完全代替BOM的escape()和unescape()方法,推荐使用。

eval()方法用于把字符串参数解释成为真正的ECMAScript语句,插入该函数的位置。

var msg="hello world";

eval("function sayHi(){alert(msg)}"); //很强大的双刃剑,使用时候小心代码注入。

sayHi(); //output "hello world"

2.Math对象

1)属性

E(值e,自然对数的底)     LN10(10的自然对数)                LN2(2的自然对数)

lOG2E(以2为底E的对数)  LOG10E(以10为底E的对数)     PI(值π)

SQRT1_2(1/2的平方根)    SQRT2(2的平方根)

2)方法

alert(Math.max(3,54,32,16)); //outputs "54" max()方法用来判断一组数中的最大值

alert(Math.min(3,54,32,16)); //outputs "3"    min()方法用来判断一组数中的最小值

alert(Math.abs(-1)); //outputs "1" abs()方法用来返回数字的绝对值

alert(Math.ceil(25.5)); //outputs "26" ceil()方法表示向上舍入取整函数

alert(Math.floor(25.5)); //outputs "25" floor()方法表示向下舍入取整函数

alert(Math.round(25.5)); //outputs  "26" round()方法是标准的四舍五入取整函数

alert(Math.exp(10)); //outputs "22026.465794806718" exp()把Math.E升到特定的幂

alert(Math.log(Math.exp(10))); /* outputs "10"  log()返回特定数字的自然对数,与exp()

本质上功能相反,返回Math.E的多少次指数才等于指定的值。*/

alert(Math.pow(2,10)); //outputs "1024"  pow()用于把数字升到指定的幂

alert(Math.sqrt(4)); //outputs "2"  sqrt()用于返回指定数字的平方根

Math对象还有一套三角函数方法,如下:

 sin(x)返回x的正弦值               cos(x)返回x的余弦值             tan(x) 返回x的正切值

 asin(x) 返回x的反正切值         acos(x)  返回x的反余切值      atan(x) 返回x的反正切值

 atan2(y,x) 返回y/x的反余弦值  

random()方法返回一个0到1之间的随机数,不包括0和1.

var iNum=Math.floor(Math.random()*10+1); //返回1到10之间的随机数

function selectFrom(iFirstValue,iLastValue){

    var iChoices=iLastValue-iFirstValue+1;

    return Math.floor(Math.random()*iChoices+iFirstValue);

}

var iNum=selectFrom(2,10);//返回2到10之间的随机数

var aColors=["red","green","blue","yellow","black","purple","brown"];

var sColor=aColors[selectFrom(0,aColors.length-1)];//返回Array中的随机项

五、宿主对象

宿主对象(host object)是所有非本地对象,即由ECMAScript实现的宿主环境提供的对

象。所有BOM和DOM都是宿主对象。

六、作用域

1.ECMAScript中只存在公共作用域,可用下划线规约私有成员,如:obj._color

2.ECMAScript没有静态作用域。

3.关键字this总是指向调用该方法的对象,使用它可在任意多个地方重用同一个函数

function showColor(){

    alert(this.color);        //引用对象属性时,必须使用this关键字。

}

var oCar1=new Object;

oCar1.color="red";

oCar1.showColor=showColor;

var oCar2=new Object;

oCar2.color="blue";

oCar2.showColor=showColor;

oCar1.showColor(); //outputs "red"

oCar2.showColor(); //outputs "blue"

七、定义类或对象

由于工厂方式、构造函数方式、原型方式等各有弊端,所以只介绍它们的混合方式

1.混合的构造函数/原型方式

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",4,25);

oCar1.drives.push("Matt");

alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"

alert(oCar2.drivers):    //outputs "Mike,Sue"

//这种方式是ECMAScript主要采用的方式

2.动态原型方式

function Car(sColor,iDoors,iMpg){

    this.color=sColor;

    this.doors=iDoors;

    this.mpg=iMpg;

    this.drivers=new Array("Mike","Sue");

    if(typeof Car._initialized=="underfined"){

        Car.prototype.showColor=function(){

            alert(this.color);

        };

    Car._initialized=true;

    }

}

//这种方式的基本思想与上一个相同,只是更符合传统OOP的类定义

3.实例

1)定义

function StringBuffer(){

    this._strings=new Array;

}

StringBuffer.prototype.append=function(str){

    this._strings.push(str);

};

StringBuffer.prototype.toString=function(str){

    return this._strings.join("");

};

2)使用

var buffer=new StringBuffer();

buffer.append("hello ");

buffer.append("world");

var result=buffer.toString(); //equal "hello world"

3)测试

var d1=new Date();

var str="";

for(var i=0; i<10000; i++){

    str+="text";

}

var d2=new Date();

document.write("Concatenation with plus: "+(d2.getTime()-d1.getTime())+"milliseconds");

var oBuffer = new StringBuffer();

d1=new Date();

for(var i=0; i<10000; i++){

    oBuffer.append("text");

}

var sResult=buffer.toString();

d2=new Date();

document.write("Concatenation with StringBuffer: "+(d2.getTime()=d1.getTime())+

"milliseconds");

//结果表明StringBuffer类比使用加号节省了100%-200%的时间。

八、修改对象

1.创建新方法

1)可以用prototype属性为任何已有的类定义新方法,就想处理自己的类一样。

Number.prototype.toHexString=function(){

    return this.toString(16);

};

var iNum=15;

alert(iNum.toHexString()); //outputs "F"

2)可以添加与已有方法无关的方法。

Array.prototype.indexOf=function(vItem){

    for(var i=0; i<this.length; i++){

        if(vItem==this[i]){

            return i;

        }

    }

    return -1;

}

var aColors=new Array("red","green","yellow");

alert(aColors.indexOf("green")); //outputs "1"

3)通过Object对象的prototype属性,来给ECMAScript中的每个本地对象添加新方法。

Object.prototype.showValue=function(){

    alert("警告:"+this.valueOf());

};

var str="hello";

var iNum=25;

str.showValue(); //outputs "警告:hello";

iNum.showValue(); //outputs "警告:25";

2.重定义已有的方法

函数名只是指向函数的指针,因此可以轻易的使它指向其他的函数。

Function.pototype.toString=function(){

    return "Function code hidden";

};

function sayHi(){

    alert("hi");

}

alert(sayHi.toString()); //outputs "Function code hidden"

输出源代码的toString()原始函数被完全废弃,没有恢复原始函数的方法,所以在覆盖

原始方法之前,存储它的指针比较安全,以便以后的使用。

Function.prototype.originalToString=Function.prototype.toString;

Function.prototype.toString=function(){

    if(this.originalToString().length>100){

        return "Function too long to dispaly.";

    }else{

        return this.originalToString();

    }

};

3.极晚绑定

技术上不存在极晚绑定,指的是能够在对象实例化后再定义它的方法。

var o=new Object;

Object.prototype.sayHi=function(){

    alert("hi");

};

o.sayHi();

不建议使用极晚绑定方法,因为很难对其跟踪和记录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值