Javascript高级编程1

本文介绍了JavaScript的基本组成部分,包括ECMAScript的核心概念、文档对象模型(DOM)及浏览器对象模型(BOM)。探讨了变量、原始类型与引用类型的特性,并对String、Number等内置对象进行了深入分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:
核心(ECMAScript):并不与任何具体浏览器相绑定.
文档对象模型(DOM):是 HTML 和 XML 的应用程序接口(API)
浏览器对象模型(BOM):主要处理浏览器窗口和框架,不过通常浏览器特定的 JavaScript 扩展都被看做 BOM 的一部分。

这些扩展包括:
弹出新的浏览器窗口
移动、关闭浏览器窗口以及调整窗口大小
提供 Web 浏览器详细信息的定位对象
提供用户屏幕分辨率详细信息的屏幕对象
对 cookie 的支持
IE 扩展了 BOM,加入了 ActiveXObject 类,可以通过 JavaScript 实例化 ActiveX 对象。

除了 DOM Core 和 DOM HTML 外,还有其他几种语言发布了自己的 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 种原始类型(primitive type),即 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,表示非数(Not a Number)。NaN 是个奇怪的特殊值。一般说来,这种情况发生在类型(String、Boolean 等)转换失败时。

NaN 的另一个奇特之处在于,它与自身不相等,这意味着下面的代码将返回 false:
alert(NaN == NaN); //输出 "false"

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

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

转换成字符串:
toString()

Number 类型的 toString() 方法比较特殊,它有两种模式,即默认模式和基模式。
默认模:
var iNum1 = 10;
var iNum2 = 10.0;
alert(iNum1.toString()); //输出 "10"
alert(iNum2.toString()); //输出 "10"

基模式:
var iNum = 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() 将把该字符之前的字符串转换成数字。

var iNum1 = parseInt("12345red"); //返回 12345
var iNum1 = parseInt("0xA"); //返回 10
var iNum1 = parseInt("56.9"); //返回 56
var iNum1 = parseInt("red"); //返回 NaN

parseInt() 方法还有基模式,可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。
var iNum1 = 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) - 把给定的值转换成字符串;

var b1 = Boolean(""); //false - 空字符串
var b2 = Boolean("hello"); //true - 非空字符串
var b1 = Boolean(50); //true - 非零数字
var b1 = Boolean(null); //false - null
var b1 = Boolean(0); //false - 零
var b1 = Boolean(new object()); //true - 对象

Number() 函数的强制类型转换与 parseInt() 和 parseFloat() 方法的处理方式相似,只是它转换的是整个值,而不是部分值。
parseInt() 和 parseFloat() 方法只转换第一个无效字符之前的字符串,因此 "1.2.3" 将分别被转换为 "1" 和 "1.2"。
用 Number() 进行强制类型转换,"1.2.3" 将返回 NaN,因为整个字符串值不能转换成数字。如果字符串值能被完整地转换,Number() 将判断是调用 parseInt() 方法还是 parseFloat() 方法。

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

var s1 = String(null); //"null"
var oNull = null;
var s2 = oNull.toString(); //会引发错误

-------------------------------------------------------------------------
ECMAScript 引用类型

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

var o = new Object();

因为 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 原始类型的引用类型。
var oBooleanObject = new Boolean(true);

Number 对象
正如你可能想到的,Number 对象是 Number 原始类型的引用类型。
var oNumberObject = new Number(68);

要得到数字对象的 Number 原始值,只需要使用 valueOf() 方法:
var iNumber = oNumberObject.valueOf();

toFixed() 方法返回的是具有指定位数小数的数字的字符串表示。
var oNumberObject = new Number(68);
alert(oNumberObject.toFixed(2)); //输出 "68.00" 参数是 2,说明应该显示两位小数

toExponential() 方法 指数
与格式化数字相关的另一个方法是 toExponential(),它返回的是用科学计数法表示的数字的字符串形式。
与 toFixed() 方法相似,toExponential() 方法也有一个参数,指定要输出的小数的位数。
var oNumberObject = new Number(68);
alert(oNumberObject.toExponential(1)); //输出 "6.8e+1"

如果不知道要用哪种形式(预定形式或指数形式)表示数字怎么办?可以用 toPrecision() 方法。
toPrecision() 方法
toPrecision() 方法根据最有意义的形式来返回数字的预定形式或指数形式。它有一个参数,即用于表示数的数字总数(不包括指数)。

var oNumberObject = new Number(68);
alert(oNumberObject.toPrecision(1)); //输出 "7e+1"

如果用 2 位数字表示 68
var oNumberObject = new Number(68);
alert(oNumberObject.toPrecision(2)); //输出 "68"

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

var oNumberObject = new Number(68);
alert(oNumberObject.toPrecision(3)); //输出 "68.0"

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

String 对象
String 对象是 String 原始类型的对象表示法。
var oStringObject = new String("hello world");

charAt() 和 charCodeAt() 方法
charAt() 方法返回的是包含指定位置处的字符的字符串:
var oStringObject = new String("hello world");
alert(oStringObject.charAt(1)); //输出 "e"

如果想得到的不是字符,而是字符代码,那么可以调用 charCodeAt() 方法:
var oStringObject = new String("hello world");
alert(oStringObject.charCodeAt(1)); //输出 "101"

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

var oStringObject = new String("hello ");
var sResult = oStringObject.concat("world");
alert(sResult); //输出 "hello world"
alert(oStringObject); //输出 "hello "

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

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

var oStringObject = new String("hello world!");
alert(oStringObject.indexOf("o")); 输出 "4"
alert(oStringObject.lastIndexOf("o")); 输出 "7"

localeCompare() 方法,对字符串进行排序。该方法有一个参数 - 要进行比较的字符串,返回的是下列三个值之一:
如果 String 对象按照字母顺序排在参数中的字符串之前,返回负数。
如果 String 对象等于参数中的字符串,返回 0
如果 String 对象按照字母顺序排在参数中的字符串之后,返回正数。
注释:如果返回负数,那么最常见的是 -1,不过真正返回的是由实现决定的。如果返回正数,那么同样的,最常见的是 1,不过真正返回的是由实现决定的。

var oStringObject = new String("yellow");
alert(oStringObject.localeCompare("brick")); //输出 "1"
alert(oStringObject.localeCompare("yellow")); //输出 "0"
alert(oStringObject.localeCompare("zoo")); //输出 "-1"

再强调一次,由于返回的值是由实现决定的,所以最好以下面的方式调用 localeCompare() 方法:
var oStringObject1 = new String("yellow");
var oStringObject2 = new String("brick");

var iResult = oStringObject1.localeCompare(oStringObject2);

if(iResult < 0) {
alert(oStringObject1 + " comes before " + oStringObject2);
} else if (iResult > 0) {
alert(oStringObject1 + " comes after " + oStringObject2);
} else {
alert("The two strings are equal");
}
采用这种结构,可以确保这段代码在所有实现中都能正确运行。

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

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

事实上,这两个方法并不完全相同,不过只在参数为负数时,它们处理参数的方式才稍有不同。
对于负数参数,slice() 方法会用字符串的长度加上参数,substring() 方法则将其作为 0 处理(也就是说将忽略它)。例如:
var oStringObject = new String("hello world");
alert(oStringObject.slice("-3")); //输出 "rld"
alert(oStringObject.substring("-3")); //输出 "hello world"
alert(oStringObject.slice("3, -4")); //输出 "lo w"
alert(oStringObject.substring("3, -4")); //输出 "hel"

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

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

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

var oStringObject = new String("Hello World");
alert(oStringObject.toLocaleUpperCase()); //输出 "HELLO WORLD"
alert(oStringObject.toUpperCase()); //输出 "HELLO WORLD"
alert(oStringObject.toLocaleLowerCase()); //输出 "hello world"
alert(oStringObject.toLowerCase()); //输出 "hello world"

instanceof 运算符

在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 "object"。ECMAScript 引入了另一个 Java 运算符 instanceof 来解决这个问题。
instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。例如:
var oStringObject = new String("hello world");
alert(oStringObject instanceof String); //输出 "true"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值