Javascript高级编程1

一个完整的JavaScript实现是由以下3个不同部分组成的:

核心(ECMAScript):并不与任何具体浏览器相绑定.

文档对象模型(DOM):是HTML和XML的应用程序接口(API)

浏览器对象模型(BOM):主要处理浏览器窗口和框架,不过通常浏览器特定的JavaScript扩展都被看做BOM的一部分。

这些扩展包括:

弹出新的浏览器窗口

移动、关闭浏览器窗口以及调整窗口大小

提供Web浏览器详细信息的定位对象

提供用户屏幕分辨率详细信息的屏幕对象

对cookie的支持

IE扩展了BOM,加入了ActiveXObject类,可以通过JavaScript实例化ActiveX对象。

除了DOMCore和DOMHTML外,还有其他几种语言发布了自己的DOM标准。这些语言都是基于XML的,每种DOM都给对应语言添加了特有的方法和接口:

可缩放矢量语言(SVG)1.0

数字标记语言(MathML)1.0

同步多媒体集成语言(SMIL)

Window对象

Navigator对象

Screen对象

History对象

Location对象

命名变量

变量名需要遵守两条简单的规则:

第一个字符必须是字母、下划线(_)或美元符号($)

余下的字符可以是下划线、美元符号或任何字母或数字字符

ECMAScript关键字的完整列表:

break,case,catch,continue,default,delete,do,else,finally,for,function,if,in,instanceof,new,return,switch,this,throw,try,typeof,var,void,while,with

原始值和引用值

在ECMAScript中,变量可以存在两种类型的值,即原始值和引用值。

原始值

存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。

引用值

存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。

ECMAScript的原始类型之一,即Undefined、Null、Boolean、Number和String型。

如果一个值是引用类型的,那么它的存储空间将从堆中分配。由于引用值的大小会改变,所以不能把它放在栈中,否则会降低变量查寻的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响。

ECMAScript提供了typeof运算符来判断一个值是否在某种类型的范围内。可以用这种运算符判断一个值是否表示一种原始类型:如果它是原始类型,还可以判断它表示哪种原始类型。

ECMAScript有5种原始类型(primitivetype),即Undefined、Null、Boolean、Number和String。

Undefined类型

如前所述,Undefined类型只有一个值,即undefined。当声明的变量未初始化时,该变量的默认值是undefined。

从未被声明过的变量,使用除typeof之外的其他运算符的话,会引起错误,因为其他运算符只能用于已声明的变量上。

Null类型

另一种只有一个值的类型是Null,它只有一个专用值null,即它的字面量。值undefined实际上是从值null派生来的,因此ECMAScript把它们定义为相等的。

alert(null==undefined);//输出"true"

Boolean类型

Number类型

ECMA-262中定义的最特殊的类型是Number类型。这种类型既可以表示32位的整数,还可以表示64位的浮点数。

整数也可以被表示为八进制(以8为底)或十六进制(以16为底)的字面量。

要创建十六进制的字面量,首位数字必须为0,后面接字母x,然后是任意的十六进制数字(0到9和A到F)。这些字母可以是大写的,也可以是小写的。

几个特殊值也被定义为Number类型。前两个是Number.MAX_VALUE和Number.MIN_VALUE,它们定义了Number值集合的外边界。所有ECMAScript数都必须在这两个值之间。不过计算生成的数值结果可以不落在这两个值之间。

当计算生成的数大于Number.MAX_VALUE时,它将被赋予值Number.POSITIVE_INFINITY,意味着不再有数字值。同样,生成的数值小于Number.MIN_VALUE的计算也会被赋予值Number.NEGATIVE_INFINITY,也意味着不再有数字值。如果计算返回的是无穷大值,那么生成的结果不能再用于其他计算。

由于无穷大数可以是正数也可以是负数,所以可用一个方法判断一个数是否是有穷的(而不是单独测试每个无穷数)。可以对任何数调用isFinite()方法,以确保该数不是无穷大。

最后一个特殊值是NaN,表示非数(NotaNumber)。NaN是个奇怪的特殊值。一般说来,这种情况发生在类型(String、Boolean等)转换失败时。

NaN的另一个奇特之处在于,它与自身不相等,这意味着下面的代码将返回false:

alert(NaN==NaN);//输出"false"

String类型

String类型的独特之处在于,它是唯一没有固定大小的原始类型

所有程序设计语言最重要的特征之一是具有进行类型转换的能力。

转换成字符串:

toString()

Number类型的toString()方法比较特殊,它有两种模式,即默认模式和基模式。

默认模:

variNum1=10;

variNum2=10.0;

alert(iNum1.toString());//输出"10"

alert(iNum2.toString());//输出"10"

基模式:

variNum=10;

alert(iNum.toString(2));//输出"1010"

alert(iNum.toString(8));//输出"12"

alert(iNum.toString(16));//输出"A"

转换成数字:

parseInt()和parseFloat()。

在判断字符串是否是数字值前,parseInt()和parseFloat()都会仔细分析该字符串。

parseInt()方法首先查看位置0处的字符,判断它是否是个有效数字;如果不是,该方法将返回NaN,不再继续执行其他操作。但如果该字符是有效数字,该方法将查看位置1处的字符,进行同样的测试。这一过程将持续到发现非有效数字的字符为止,此时parseInt()将把该字符之前的字符串转换成数字。

variNum1=parseInt("12345red");//返回12345

variNum1=parseInt("0xA");//返回10

variNum1=parseInt("56.9");//返回56

variNum1=parseInt("red");//返回NaN

parseInt()方法还有基模式,可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。

variNum1=parseInt("AF",16);//返回175

parseFloat()方法与parseInt()方法的处理方式相似,从位置0开始查看每个字符,直到找到第一个非有效的字符为止,然后把该字符之前的字符串转换成整数。

不过,对于这个方法来说,第一个出现的小数点是有效字符。如果有两个小数点,第二个小数点将被看作无效的。parseFloat()会把这个小数点之前的字符转换成数字。这意味着字符串"11.22.33"将被解析成11.22。

使用parseFloat()方法的另一不同之处在于,字符串必须以十进制形式表示浮点数,而不是用八进制或十六进制。该方法会忽略前导0,所以八进制数0102将被解析为102。对于十六进制数0xA,该方法将返回NaN,因为在浮点数中,x不是有效字符。

强制类型转换:

ECMAScript中可用的3种强制类型转换如下:

Boolean(value)-把给定的值转换成Boolean型;

Number(value)-把给定的值转换成数字(可以是整数或浮点数);

String(value)-把给定的值转换成字符串;

varb1=Boolean("");//false-空字符串

varb2=Boolean("hello");//true-非空字符串

varb1=Boolean(50);//true-非零数字

varb1=Boolean(null);//false-null

varb1=Boolean(0);//false-零

varb1=Boolean(newobject());//true-对象

Number()函数的强制类型转换与parseInt()和parseFloat()方法的处理方式相似,只是它转换的是整个值,而不是部分值。

parseInt()和parseFloat()方法只转换第一个无效字符之前的字符串,因此"1.2.3"将分别被转换为"1"和"1.2"。

用Number()进行强制类型转换,"1.2.3"将返回NaN,因为整个字符串值不能转换成数字。如果字符串值能被完整地转换,Number()将判断是调用parseInt()方法还是parseFloat()方法。

强制转换成字符串和调用toString()方法的唯一不同之处在于,对null和undefined值强制类型转换可以生成字符串而不引发错误:

vars1=String(null);//"null"

varoNull=null;

vars2=oNull.toString();//会引发错误

-------------------------------------------------------------------------

ECMAScript引用类型

引用类型通常叫做类(class)。

引用类型通常叫做类(class),也就是说,遇到引用值,所处理的就是对象。

varo=newObject();

因为ECMAScript中的Object对象与Java中的java.lang.Object相似,ECMAScript中的所有对象都由这个对象继承而来,Object对象中的所有属性和方法都会出现在其他对象中,所以理解了Object对象,就可以更好地理解其他对象。

Object对象具有下列属性:

constructor

对创建对象的函数的引用(指针)。对于Object对象,该指针指向原始的Object()函数。

Prototype

对该对象的对象原型的引用。对于所有的对象,它默认返回Object对象的一个实例。

hasOwnProperty(property)

判断对象是否有某个特定的属性。必须用字符串指定该属性。

(例如,o.hasOwnProperty("name"))

IsPrototypeOf(object)

判断该对象是否为另一个对象的原型。

PropertyIsEnumerable

判断给定的属性是否可以用for...in语句进行枚举。

ToString()

返回对象的原始字符串表示。

ValueOf()

返回最适合该对象的原始值。对于许多对象,该方法返回的值都与ToString()的返回值相同。

Boolean对象

Boolean对象是Boolean原始类型的引用类型。

varoBooleanObject=newBoolean(true);

Number对象

正如你可能想到的,Number对象是Number原始类型的引用类型。

varoNumberObject=newNumber(68);

要得到数字对象的Number原始值,只需要使用valueOf()方法:

variNumber=oNumberObject.valueOf();

toFixed()方法返回的是具有指定位数小数的数字的字符串表示。

varoNumberObject=newNumber(68);

alert(oNumberObject.toFixed(2));//输出"68.00"参数是2,说明应该显示两位小数

toExponential()方法指数

与格式化数字相关的另一个方法是toExponential(),它返回的是用科学计数法表示的数字的字符串形式。

与toFixed()方法相似,toExponential()方法也有一个参数,指定要输出的小数的位数。

varoNumberObject=newNumber(68);

alert(oNumberObject.toExponential(1));//输出"6.8e+1"

如果不知道要用哪种形式(预定形式或指数形式)表示数字怎么办?可以用toPrecision()方法。

toPrecision()方法

toPrecision()方法根据最有意义的形式来返回数字的预定形式或指数形式。它有一个参数,即用于表示数的数字总数(不包括指数)。

varoNumberObject=newNumber(68);

alert(oNumberObject.toPrecision(1));//输出"7e+1"

如果用2位数字表示68

varoNumberObject=newNumber(68);

alert(oNumberObject.toPrecision(2));//输出"68"

如果指定的位数多于需要的位数

varoNumberObject=newNumber(68);

alert(oNumberObject.toPrecision(3));//输出"68.0"

在这种情况下,toPrecision(3)等价于toFixed(1),输出的是"68.0"。

alert(oNumberObject.toPrecision(3));//输出"68.0"

String对象

String对象是String原始类型的对象表示法。

varoStringObject=newString("helloworld");

charAt()和charCodeAt()方法

charAt()方法返回的是包含指定位置处的字符的字符串:

varoStringObject=newString("helloworld");

alert(oStringObject.charAt(1));//输出"e"

如果想得到的不是字符,而是字符代码,那么可以调用charCodeAt()方法:

varoStringObject=newString("helloworld");

alert(oStringObject.charCodeAt(1));//输出"101"

concat()方法,用于把一个或多个字符串连接到String对象的原始值上。该方法返回的是String原始值,保持原始的String对象不变。

varoStringObject=newString("hello");

varsResult=oStringObject.concat("world");

alert(sResult);//输出"helloworld"

alert(oStringObject);//输出"hello"

ndexOf()和lastIndexOf()方法,返回的都是指定的子串在另一个字符串中的位置,如果没有找不到子串,则返回-1。

这两个方法的不同之处在于,indexOf()方法是从字符串的开头(位置0)开始检索字符串,而lastIndexOf()方法则是从字符串的结尾开始检索子串。

varoStringObject=newString("helloworld!");

alert(oStringObject.indexOf("o"));输出"4"

alert(oStringObject.lastIndexOf("o"));输出"7"

localeCompare()方法,对字符串进行排序。该方法有一个参数-要进行比较的字符串,返回的是下列三个值之一:

如果String对象按照字母顺序排在参数中的字符串之前,返回负数。

如果String对象等于参数中的字符串,返回0

如果String对象按照字母顺序排在参数中的字符串之后,返回正数。

注释:如果返回负数,那么最常见的是-1,不过真正返回的是由实现决定的。如果返回正数,那么同样的,最常见的是1,不过真正返回的是由实现决定的。

varoStringObject=newString("yellow");

alert(oStringObject.localeCompare("brick"));//输出"1"

alert(oStringObject.localeCompare("yellow"));//输出"0"

alert(oStringObject.localeCompare("zoo"));//输出"-1"

再强调一次,由于返回的值是由实现决定的,所以最好以下面的方式调用localeCompare()方法:

varoStringObject1=newString("yellow");

varoStringObject2=newString("brick");

variResult=oStringObject1.localeCompare(oStringObject2);

if(iResult<0){

alert(oStringObject1+"comesbefore"+oStringObject2);

}elseif(iResult>0){

alert(oStringObject1+"comesafter"+oStringObject2);

}else{

alert("Thetwostringsareequal");

}

采用这种结构,可以确保这段代码在所有实现中都能正确运行。

slice()和substring()

这两种方法返回的都是要处理的字符串的子串,都接受一个或两个参数。第一个参数是要获取的子串的起始位置,第二个参数(如果使用的话)是要获取子串终止前的位置(也就是说,获取终止位置处的字符不包括在返回的值内)。如果省略第二个参数,终止位就默认为字符串的长度。

与concat()方法一样,slice()和substring()方法都不改变String对象自身的值。它们只返回原始的String值,保持String对象不变。

事实上,这两个方法并不完全相同,不过只在参数为负数时,它们处理参数的方式才稍有不同。

对于负数参数,slice()方法会用字符串的长度加上参数,substring()方法则将其作为0处理(也就是说将忽略它)。例如:

varoStringObject=newString("helloworld");

alert(oStringObject.slice("-3"));//输出"rld"

alert(oStringObject.substring("-3"));//输出"helloworld"

alert(oStringObject.slice("3,-4"));//输出"low"

alert(oStringObject.substring("3,-4"));//输出"hel"

toLowerCase()、toLocaleLowerCase()、toUpperCase()和toLocaleUpperCase()

toLowerCase()和toUpperCase()方法是原始的,是以java.lang.String中相同方法为原型实现的。

toLocaleLowerCase()和toLocaleUpperCase()方法是基于特定的区域实现的(与localeCompare()方法相同)。在许多区域中,区域特定的方法都与通用的方法完全相同。

varoStringObject=newString("HelloWorld");

alert(oStringObject.toLocaleUpperCase());//输出"HELLOWORLD"

alert(oStringObject.toUpperCase());//输出"HELLOWORLD"

alert(oStringObject.toLocaleLowerCase());//输出"helloworld"

alert(oStringObject.toLowerCase());//输出"helloworld"

instanceof运算符

在使用typeof运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回"object"。ECMAScript引入了另一个Java运算符instanceof来解决这个问题。

instanceof运算符与typeof运算符相似,用于识别正在处理的对象的类型。与typeof方法不同的是,instanceof方法要求开发者明确地确认对象为某特定类型。例如:

varoStringObject=newString("helloworld");

alert(oStringObjectinstanceofString);//输出"true"

相关推荐