内置对象的定义:由ECMAScript实现提供的, 不依赖于鹤环境的对象,这些对象在ECMAScript程序执行之前就已经存在了.
开发人员不必显式地实例化内置对象,因为它们已经实例化了.
前面介绍了大多数内置对象,如Object,Array和String.ECMA-262还定义了两个单体内置对象:Global和Math.
5.7.1 Global对象
没有全局变量或全局函数;所有在全局作用域中定义的属性和函数,都是Global(全局)对象的属性.
诸如isNaN(),isFinite(),parseInt()以及parseFloat(),实际上全都是Global对象的方法.除此之外,Global对象还包含其他一些方法.
1.URL编码方法
Global对象的encodeURL()和encodeURIComponent()方法可以对URI(Uniform Resource Identifiers)进行编码,以便发送给浏览器.有效的URI中不能包含某些字符,例如空格.而这两个URI编码方法都可以对URI进行编码,它们用特殊的UTF-8编码替换所有无效的字符,从而让浏览器能够接受和理解.
其中,encodeURI()主要用于整个URI,而encodeURIComponent()主要用于对URI中的某一段进行编码.
它们的主要区别在于:encodeURI()不会对本身属于URI的特殊字符进行编码,例如冒号,正斜杠,问号和井字号;而encodeURIComponent()则会对它发现的任何非标准字符进行编码.
var uri="http://www.wrox.com/illegal value.htm#start"; console.log(encodeURI(uri));//http://www.wrox.com/illegal%20value.htm#start console.log(encodeURIComponent(uri));//http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start
使用encodeURI()编码后的结果是除了空格之外的其他字符都原封不去,只有空格被替换成了%20.而encodeURIComponent()方法则会使用对应的编码替换所有非字母数字字符.
一般来说 ,我们使用encodeURIComponent()方法的时候要比使用encodeURI()更多,因为在实践中更常见的是对查询字符串参数而不是对基础URI进行编码.
与encodeURI()和encodeURIComponent()对应的两个方法是decodeURI()和decodeURIComponent().其中,decodeURI()只能对使用encodeURI()替换的字符进行解码.它也仅将%20替换成一个空格,对不是encodeURI()的不进行解码.同样的,decodeURIComponent()能够解码使用encodeURIComponent()编码的所有字符,即它可以解码任何特殊字符的编码.
var uri1="http://www.wrox.com/illegal%20value.htm#start"; console.log(decodeURI(uri1));//http://www.wrox.com/illegal value.htm#start var uri1="http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start"; console.log(decodeURIComponent(uri1));//http://www.wrox.com/illegal value.htm#start
调用decodeURIComponent()输出结果中,所有特殊字符的编码都被替换成了原来的字符,得到了一个未经转义的字符串(但这个字符串并不是个有效的URI).
URI就法能够编码所有的Unicode字符,而原来的方法只能正确地编码ASCII字符.在开发实践中,特别是在产品级的代码中,一定 要使用URI方法,不要使用escape()和unescape()方法.
2.eval()方法
eval()方法大概算ECMAScript语言中最强大的一个方法,eval()方法就像是一个完整的ECMAScript解析器,它只接受一个参数,即要执行的ECMAScript(或JavaScript字符串).
eval("alert('hi')");
等价于
alert("hi");
当解析器发现代码中调用eval()方法时,它会将传入的参数当作实际的ECMAScript语句来解析,然后把执行结果插入到原位置.通过eval()执行的代码被认为是包含该次调用的执行环境的一部分,因此被执行的代码具有与该执行环境相同的作用域链.这意味着通过eval()执行的代码可以引用在包含环境中定义的变量.
var msg="hello world"; eval("alert(msg)");//hello world
变量msg是在eval()调用的环境之外定义的,但其中调用的alert()仍然能够显示"hello world".这是因为上面第二行代码最终被替换成了一行真正的代码.同样的我们也可以在eval()调用中定义一个函数,然后再在该调用的外部代码中引用这个函数.对于变量也一样
eval("var msg='hello world';"); alert(msg);//hello world
在eval()中创建的任何变量或函数都不会被提升,因为在解析代码的时候,它们被包含在一个字符串中,它们只在eval()执行的时候创建.
严格模式下,在外部访问不到eval()中创建的任何变量或函数,因此前面两个例子在严格模式下会导致错误.
同样,在严格模式下,为eval()赋值也会导致错误
"use strict"; eval="hi";//Uncaught SyntaxError: Unexpected eval or arguments in strict mode
能够解释代码字符串的能力非常强大,但也非常危险.因此在使用eval()时必须极为谨慎,特别是在用它执行用户输入数据的情况下.否则,可能会有恶意用户输入威胁你的站点或应用程序安全的代码(即所谓的代码注入).
3.Global对象的属性
Global对象还包含一些属性,例如,特殊的值undefined,NaN以及Infinity都是Global对象的属性.此外,所有原生引用类型的构造函数,像Object和Function,也都是Global对象的属性.
下面列出Global对象的所有属性.
属性 | 说明 | 属性 | 说明 | |
undefined | 特殊值undefined | Date | 构造函数Date | |
NaN | 特殊值NaN | RegExp | 构造函数RegExp | |
Infinity | 特殊值Infinity | Error | 构造函数RegExp | |
Object | 构造函数Object | EvalError | 构造函数EvalError | |
Array | 构造函数Array | RangeError | 构造函数RangeError | |
Function | 构造函数Function | ReferenceError | 构造函数ReferenceError | |
Boolean | 构造函数Boolean | SyntaxError | 构造函数SyntaxError | |
String | 构造函数String | TypeError | 构造函数TypeError | |
Number | 构造函数Number | URIError | 构造函数URIError |
ECMAScript 5明确禁止给undefined,NaN和Infinity赋值,这样做即使在非严格模式下也会导致错误.
4.window对象
ECMAScript虽然没有指出如何直接访问Global对象,但Web浏览器都是将这个全局对象作为window对象的一部分加以实现的.因此,在全局作用域中声明的所有变量和函数,都将成为window对象的属性.
var color="red"; function sayColor(){ alert(window.color); } window.sayColor();//red
另一种取得Global对象的方法是使用以下代码
var global=function(){ return this; }()
以上代码创建了一个立即调用的函数表达式,返回this的值.如前所述,在没有给函数明确指定this值的情况下(无论是通过将函数添加为对象的方法,还是通过调用call()和apply()),this值等于Global对象.而像这样通过简单地返回this来取得Global对象,在任何执行环境下都是可行的.
5.7.2 Math对象
1.Math对象的属性
属性 | 说明 |
Math.E | 自然对数的底数,即常量e的值 |
Math.LN10 | 10的自然对数 |
Math.LN2 | 2的自然对象 |
Math.LOG2E | 以2为底e的对数 |
Math.LOG10E | 以10为底e的对数 |
Math.PI | п的值 |
Math.SQRT1_2 | 1/2的平方根(即2的平方根的倒数) |
Math.SQRT2 | 2的平方根 |
2.min()和max()方法
Math对象下的min()和max()方法用于确定一组数值中的最小值和最大值.这两个方法都可以接收任何多个数值参数.
var values=[1,2,3,4,5,6,7,8]; var max=Math.max.apply(Math,values); console.log(max)//8
这个技巧的关键是把Math对象作为apply()的第一个参数,从而正确地设置this值.然后,可以将任何数组作为第二个参数.
3.舍入方法
Math.ceil()执行向上舍入,即它总是将数值向上舍入为最接近的整数.
Math.floor()执行向下舍入,即它总是将数值向下舍入为最接近的整数.
Math.round()执行标准舍入,即它总是将数值四舍五入为最接近的整数.
4.random()方法
Math.random()方法返回大于等于0小于1的一个随机数.对于某些问点来说,这个方法非常实用,因为可以利用它来随机显示一些名人名言和新闻事件.
值=Math.floor(Math.random()*可能值的总和+第一个可能的值)
下面为选择一个1到10之间的数值
var num=Math.floor(Math.random()*10+1);
下面为选择介于2到10之间的值
var num=Math.floor(Math.random()*9+2);
function selectFrom(lowerValue,upperValue){ var choices=upperValue-lowerValue+1; return Math.floor(Math.random()*choices+lowerValue); } var num=selectFrom(2,10); alert(num);//介于2和10之间(包括2和10)的一个数值
函数selectFrom()接受两个参数:应该返回的最小值和最大值.这样,通过调用selectFrom(2,10)就可以得到一个介于2和10之间(包括2和10)的数值了.利用这个函数,可以方便地从数组中随机取出一项,例如:
var colors=["red","green","blue","yellow","black","purple","brown"]; var color=colors[selectFrom(0,colors.length-1)]; console.log(color);//可能是数组中包含的任何一个字符串
在这个例子中,传递给selectFrom()的第二个参数就是数组的长度减1,也就是数组中最后一项的位置.
5.其他方法
方法 | 说明 | 方法 | 说明 | |
Math.abs(num) | 返回num的绝对值 | Math.asin(x) | 返回x的反正统值 | |
Math.exp(num) | 返回Math.E的num次幂 | Math.atan(x) | 返回x的反正切值 | |
Math.log(num) | 返回num的自然对数 | Math.atan2(y,x) | 返回y/x的反正切值 | |
Math.pow(num,power) | 返回num的power次幂 | Math.cos(x) | 返回x的余弦值 | |
Math.sqrt(num) | 返回num的平方根 | Math.sin(x) | 返回x的正弦值 | |
Math.acos(x) | 返回x的反余弦值 | Math.tan(x) | 返回x的正切值 |
虽然ECMA-262规定了这些方法,但不同实现可能会对这些方法采用不同的算法.
5.8 小结
对象在JavaScript中被称为引用类型的值,而且有一些内置的引用类型可以用来创建特定的对象,现简要总要如下:
引用类型与传统面向对象程序设计中的类相似,但实现不同;
Object是一个基础类型,其他所有类型都从Object继承了基本的行为;
Array类型是一组值值的有序列表,同时还提供了操作和转换这些值的功能.
Date类型提供了有关日期和时间的信息,包括当前日期和时间以及的相关的计算功能.
RegExp类型是ECMAScript支持正则表达式的一个接口,提供了最基本的和一些高级的正则表达式功能.
函数实际上是Function类型的实例,因此函数也是对象;而这一点正是JavaScript最有特色的地方.由于函数是对象,所以函数也拥有方法,可以用来增强其行为.
因为有了基本包装类型,所以JavaScript中的基本类型值可以被当作对象来访问.三种基本包装类型分别是:Boolean,Number和String.以下是它们共同的特殊:
每个包装类型都映射到同名的基本类型;
在读取模式下访问基本类型值时,就会创建对应的基本包装类型的一个对象,从而方便了数据操作;
操作基本类型值的语句一经执行完毕,就会立即销毁新创建的包装对象.
在所有代码执行之前,作用域中就已经存在两个内置对象:Global和Math.在大多数ECMAScript实现中都不能直接访问Global对象,不过,Web浏览器实现了承担该角色的window对象.全局变量和函数都是Global对象的属性.Math对象提供了很多属性和方法,用于辅助完成复杂的数学计算任务.