《JavaScript 闯关记》之单体内置对象

ECMA-262 对停放对象的定义是「由 JavaScript
实现提供的、不借助让宿主环境的对象,这些目标在 JavaScript
程序执行之前便曾经存在了」。意思乃是,开发人员不必显式地实例化内置对象,因为她就实例化了。前面我们曾经介绍了绝大多数置对象,例如
ObjectArrayString。ECMA-262
还定义了少数只单体内置对象:GlobalMath

Global 对象

Global 对象足以说凡是 JavaScript
中最特别之一个靶了,因为不管你打什么角度上看,这个目标还是不设有的。Global
对象在某种意义上是作一个极的「兜底儿对象」来定义之。换句话说,不属其他其他对象的属性与方法,最终还是它的性与章程。所有以全局作用域中定义的性质和函数,都是
Global 对象的特性。本书前面介绍了之那些函数,诸如
isNaN()isFinite()parseInt() 以及 parseFloat(),实际上都是
Global 对象的方法。除此之外,Global 对象还含其他有办法。

URI 编码方法

Global 对象的 encodeURI()encodeURIComponent() 方法可本着
URI(Uniform Resource
Identifiers,通用资源标识符)进行编码,以便发送给浏览器。有效之 URI
中莫克包含某些字符,例如空格。而当时简单只 URI 编码方法就可针对 URI
进行编码,它们用非常的 UTF-8
编码替换所有无效的字符,从而被浏览器会接受和了解。

其中,encodeURI() 主要用以所有 URI,而 encodeURIComponent()
主要用来对 URI 中的某部同段展开编码。它们的重大区别在于,encodeURI()
不见面指向自身属于 URI
的特殊字符进行编码,例如冒号、正斜杠、问号及井字号;而
encodeURIComponent()
则会针对它发现的另外不标准字符进行编码。来拘禁下的例证。

var uri = "http://shijiajie.com/illegal value.htm#start";

console.log(encodeURI(uri));
// "http://shijiajie.com/illegal%20value.htm#start"

console.log(encodeURIComponent(uri));
// "http%3A%2F%2Fshijiajie.com%2Fillegal%20value.htm%23start"

使用 encodeURI()
编码后的结果是除空格之外的任何字符都原封无动,只有空格被替换成了
%20。而 encodeURIComponent()
方法则会动用相应之编码替换所有非字母数字字符。这为正是可以本着任何 URI
使用 encodeURI(),而不得不对附加以存活 URI 后面的字符串使用
encodeURIComponent() 的案由所在。

相似的话,我们用 encodeURIComponent() 方法的时刻如果较用
encodeURI() 更多,因为在实践中更广泛的凡对查询字符串参数而不是针对性基础
URI 进行编码。

encodeURI()encodeURIComponent() 方法对应之星星个艺术分别是
decodeURI()decodeURIComponent()。其中,decodeURI() 只能对下
encodeURI() 替换的字符进行解码。例如,它可是将 %20
替换成一个空格,但未会见指向 %23 作任何处理,因为 %23 表示井字号
#,而井字号不是运用 encodeURI()
替换的。同样地,decodeURIComponent() 能够解码使用
encodeURIComponent()
编码的享有字符,即其可解码任何特殊字符的编码。来拘禁下的例子:

var uri = "http%3A%2F%2Fshijiajie.com%2Fillegal%20value.htm%23start";

console.log(decodeURI(uri));
// http%3A%2F%2Fshijiajie.com%2Fillegal value.htm%23start

console.log(decodeURIComponent(uri));
// http://shijiajie.com/illegal value.htm#start

这里,变量 uri 包含在一个出于 encodeURIComponent()
编码的字符串。在首先涂鸦调整用 decodeURI() 输出的结果受,只有 %20
被轮换成了空格。而以其次坏调整用 decodeURIComponent()
输出的结果丁,所有特殊字符的编码还深受调换成了本的字符,得到了一个未经转义的字符串(但这字符串并无是一个行之有效的
URI)。

eval() 方法

eval() 方法就是如是一个一体化的 JavaScript
解析器,它不过领一个参数,即要履行之 JavaScript 字符串。看下面的例证:

eval("console.log('hi')");

即时行代码的意图等价于下面这行代码:

console.log("hi");

当解析器发现代码中调用 eval() 方法时,它会用盛传的参数作为实际的
JavaScript 语句来分析,然后把执行结果插入到原岗位。通过 eval()
执行的代码被认为是含该次调用的推行环境的平部分,因此吃执行之代码有和拖欠实施环境一致的意向域链。这意味通过
eval() 执行的代码可以引用在含环境受到定义之变量,举个例证:

var msg = "hello world";
eval("console.log(msg)");    // "hello world"

可见,变量 msg 是在 eval() 调用的条件外定义的,但内部调用的
console.log() 仍然会显得
"hello world"。这是坐地方第二实施代码最终为调换成了一如既往实践确实的代码。同样地,我们吧堪当
eval() 调用着定义一个函数,然后再于拖欠调用的标代码中援这函数:

eval("function sayHi() { console.log('hi'); }");
sayHi();    // "hi"

显然,函数 sayHi() 是在 eval() 内部定义之。但出于对 eval()
的调用最终会于调换成定义函数的其实代码,因此可以产一行调用 sayHi()
。对于变量也同:

eval("var msg = 'hello world';");
console.log(msg);     // "hello world"

eval()
中开创的旁变量或函数都未会见为提升,因为在分析代码的时节,它们叫含有在一个字符串中;它们才当
eval() 执行之早晚创建。

严加模式下,在外表看不交 eval()
中创造的另变量或函数,因此前两单例都见面造成错误。同样,在严格模式下,为
eval 赋值也会招致错误:

"use strict";
eval = "hi";   // causes error

克说代码字符串的力量十分强,但为大惊险。因此在行使 eval()
时要多小心,特别是在用其执行用户输入数据的状态下。否则,可能会见发生恶意用户输入威胁而的站点还是应用程序安全之代码(即所谓的代码注入)。

Global 对象的性

Global
对象还含有性质,其中有些特性已当本书前面介绍了了。例如,特殊之值
undefinedNaN 以及 Infinity 都是 Global
对象的性。此外,所有原生引用类型的构造函数,像 Object
Function,也都是 Global 对象的习性。下表列出了 Global
对象的有属性。

属性 说明 属性 说明
undefined 特殊值undefined Date 构造函数Date
NaN 特殊值NaN RegExp 构造函数RegExp
Infinity 特殊值Infinity Error 构造函数Error
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 明确禁吃 undefinedNaNInfinity
赋值,这样做就在非严格模式下吧会见招错误。

window 对象

JavaScript 虽然从未指出什么直接看 Global 对象,但 Web
浏览器还是用以此大局对象作为 window
对象的一模一样组成部分加以落实的。因此,在大局作用域中声称的兼具变量和函数,就还变成了
window 对象的性。来拘禁下的事例。

var color = "red";

function sayColor(){
    console.log(window.color);
}

window.sayColor();  // "red"

JavaScript 中的 window 对象除了去规定之 Global
对象的角色外,还当了累累别的任务。

Math 对象

JavaScript 还吧保留数学公式和消息提供了一个官位置,即 Math
对象。与我们在 JavaScript 直接编写的计功能相比,Math
对象提供的测算功能实施起来如赶快得多。Math
对象被还提供了援助完成这些计算的属性与方。

Math 对象的性能

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的平方根

min()max() 方法

Math
对象还噙众多方式,用于救助完成简单和复杂的数学计算。其中,min()
max()
方法用于确定一组数值中的最小值和最要命价值。这有限只措施还可以接纳任意多独数值参数,如下面的例子所示。

var max = Math.max(3, 54, 32, 16);
console.log(max);    // 54

var min = Math.min(3, 54, 32, 16);
console.log(min);    // 3

苟找到数组中之太充分或极小价,可以像下这样使 apply() 方法。

var values = [1, 2, 3, 4, 5, 6, 7, 8];
var max = Math.max.apply(Math, values);
console.log(max);   // 8

其一技术的首要是将 Math 对象作为 apply()
的第一独参数,从而对地安装 this
值。然后,可以用另数组作为次独参数。

舍入方法

下面来介绍以有些数值舍入为整数的几只点子:Math.ceil()Math.floor()
Math.round()。这三独主意分别随下列舍入规则:

  • Math.ceil() 执行向上舍入,即其总是拿数值向上舍入为极端相仿的平头;
  • Math.floor() 执行于下舍入,即她连接拿数值为下舍入为无限相仿的平头;
  • Math.round() 执行标准舍入,即她连接以数值四放弃五抱乎最相近的平头。

脚是采取这些艺术的言传身教:

console.log(Math.ceil(25.9));     // 26
console.log(Math.ceil(25.5));     // 26
console.log(Math.ceil(25.1));     // 26

console.log(Math.round(25.9));    // 26
console.log(Math.round(25.5));    // 26
console.log(Math.round(25.1));    // 25

console.log(Math.floor(25.9));    // 25
console.log(Math.floor(25.5));    // 25
console.log(Math.floor(25.1));    // 25

random() 方法

Math.random()
方法返回介于0以及1次一个无限制数,包括0而非包1。对于一些站点来说,这个方法好实用,因为好行使其来随便亮有名人名言和情报事件。套用下面的公式,就可下
Math.random() 从某个整数范围外肆意选一个价值。

值 = Math.floor(Math.random() * 可能值的总数 + 第一个可能的值)

公式中因故到了 Math.floor() 方法,这是因 Math.random()
总返回一个稍微数值。而因此是有些数值乘以一个平头,然后重新增长一个整数,最终结出依然还是一个小数。举例来说,如果你想选一个1届10里头的数值,可以像下这样编写代码:

var num = Math.floor(Math.random() * 10 + 1);

总共发生10独可能的值(1届10),而首先只可能的值是1。而如果想只要选一个在乎2暨10里边的值,就应有拿地方的代码改化这么:

var num = Math.floor(Math.random() * 9 + 2);

自从2数至10要数9独数,因此恐怕价值的总和就是9,而首先单或的价就是2。多数状下,其实还足以通过一个函数来测算可能价值的总额和率先单或的值,例如:

function selectFrom(lowerValue, upperValue) {
    var choices = upperValue - lowerValue + 1;
    return Math.floor(Math.random() * choices + lowerValue);
}

var num = selectFrom(2, 10);
console.log(num);   // 介于2和10之间(包括2和10)的一个数值

函数 selectFrom()
接受两单参数:应该归的太小值和无限深价值。而用最好酷价值减最小值再加1得到了也许价值的总数,然后她而将这些数值套用到了前头的公式中。这样,通过调用
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);  // 可能是数组中包含的任何一个字符串

另外艺术

Math
对象被尚隐含其他有同成就各种简单或复杂计算有关的方法,但详细座谈中各一个法的底细以及适用情形不止了本书的克。下面我们尽管吃出一个表格,其中列有了这些从没介绍及之
Math 对象的方。

方法 说明
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
规定了这些方法,但不同实现可能会见指向这些点子以不同的算法。毕竟,计算某个值的正弦、余弦和正切的点子各种各样。也刚好以这么,这些办法以不同之落实中或许会见时有发生异之精度。

关卡

// 如何高效产生m个n范围内的不重复随机数(m<=n)
var getRandomNumber = function(n, m){
    // 待实现方法体
}
console.log(getRandomNumber(20, 3));  // 8,4,19

更多

关爱微信公众号「劼哥舍」回复「答案」,获取关卡详解。
关注
https://github.com/stone0090/javascript-lessons,获取最新动态。