ESMA-262
内置对象的定义是“任何由ECMAScript
实现提供、与宿主环境无关,并在ECMAScript
程序开始执行时就存在的对象”。
这就意味着,开发者不用显式实例化内置对象,因为它们已经实例化好了。前面我们已经接触了大部分内置对象,包括Object
、Array
和String
。本节介绍ECMA-262
定义的另外两个单例内置对象:Global
和Math
。
Global
对象是ECMAScript
中最特别的对象,因为代码不会显式地访问它。它所针对的是不属于任何对象的属性和方法。在全局作用域中定义的变量和函数都会变成Global
对象的属性 。之前说的 isNaN()
、isFinite()
、parseInt()
和parseFloat()
,实际上都是Global
对象的方法。
URL 编码方法
encodeURI()
和encodeURIComponent()
方法用于编码统一资源标识符(URI
),以便传给浏览器。
有效的**URI**
不能包含某些字符,比如空格。使用**URI**
编码方法来编码**URI**
可以让浏览器能够理解它们, 同时又以特殊的**UTF-8**
编码替换掉所有无效字符。
:::info
ecnodeURI()
:该方法用于对整个URI
进行编码,比如:”www.wrox.com/illegal value.js
“encodeURIComponent()
:该方法用于编码URI
中单独的组件,比如前面URL
中的”illegal value.js
“。
这两个方法的主要区别是,encodeURI()
不会编码属于URL
组件的特殊字符,比如冒号、斜杠、问号、 井号,而encodeURIComponent()
会编码它发现的所有非标准字符。
:::
let uri = "http://www.wrox.com/illegal value.js#start";
console.log(encodeURI(uri));
// "http://www.wrox.com/illegal%20value.js#start"
console.log(encodeURIComponent(uri));
// "http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.js%23start"
以上代码使用encodeURI()
编码后, 除空格被替换为%20
之外,没有任何变化。 而encodeURIComponent()
方法将所有非字母字符都替换成了相应的编码形式。
:::info
与上面两个方法相对的是decodeURI()
和decodeURIComponent()
。decodeURI()
:对ecnodeURI()
编码后的字符进行解码。decodeURIComponent()
:对encodeURIComponent()
编码后的字符进行解码。
:::
let uri = "http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.js%23start";
console.log(decodeURI(uri));
// http%3A%2F%2Fwww.wrox.com%2Fillegal value.js%23start
console.log(decodeURIComponent(uri));
// http:// www.wrox.com/illegal value.js#start
以上代码URI
变量中包含一个使用encodeURIComponent()
编码过的字符串。 首先输出的是使用 decodeURI()
解码的结果,可以看到只用空格替换了%20
。然后是使用decodeURIComponent()
解码的结果,其中替换了所有特殊字符,并输出了没有包含任何转义的字符串。
Math 对象
ECMAScript
提供了Math
对象作为保存数学公式、信息和计算的地方。Math
对象提供了一些辅助 计算的属性和方法。
min() / max()
:::info 用于比较一组数中的最小值/最大值。 :::
let max = Math.max(3, 54, 32, 16);
console.log(max); // 54
let min = Math.min(3, 54, 32, 16);
console.log(min); // 3
要知道数组中的最大值和最小值,可以像下面这样使用扩展操作符:
let values = [1, 2, 3, 4, 5, 6, 7, 8];
let max = Math.max(...val);
ceil() / floor()
:::info 用于把小数值向上/向下舍入为整数。 :::
console.log(Math.ceil(25.9)); // 26
console.log(Math.ceil(25.5)); // 26
console.log(Math.ceil(25.1)); // 26
console.log(Math.floor(25.9)); // 25
console.log(Math.floor(25.5)); // 25
console.log(Math.floor(25.1)); // 25
round() / fround()
:::info
round()
方法用于将小数四舍五入为整数。fround()
方法返回数值最接近的单精度(32 位)浮点值表示。
:::
console.log(Math.round(25.9)); // 26
console.log(Math.round(25.5)); // 26
console.log(Math.round(25.1)); // 25
console.log(Math.fround(0.4)); // 0.4000000059604645
console.log(Math.fround(0.5)); // 0.5
console.log(Math.fround(25.9)); // 25.899999618530273
random()
:::info 该方法返回一个 0~1 之间的随机数(其中包括 0 但是不包括 1) :::
console.log(Math.random()); // 0.9477678288462901
可利用以下公式来实现自定义区间的随机数:
:::info
例如想取 10~20 之间的随机数:Math.floor(10 + (20-10) * Math.random());
:::
var num = Math.floor(10 + (20-10) * Math.random());
console.log(num);
// 12
// 16
// 18
// 13
其他方法
Math
对象还有很多涉及各种简单或高阶数运算的方法(不常用)。
方法 | 说明 |
---|---|
Math.abs(x) |
返回x 的绝对值 |
Math.exp(x) |
返回Math.E 的x 次幂 |
Math.expm1(x) |
等于Math.exp(x) - 1 |
Math.log(x) |
返回x 的自然对数 |
Math.log1p(x) |
等于1 + Math.log(x) |
Math.pow(x, power) |
返回x 的power 次幂 |
Math.hypot(...nums) |
返回nums 中每个数平方和的平方根 |
Math.clz32(x) |
返回 32 位整数x 的前置零的数量 |
Math.sign(x) |
返回表示x 符号的 1、0、-0 或-1 |
Math.trunc(x) |
返回x 的整数部分,删除所有小数 |
Math.sqrt(x) |
返回x 的平方根 |
Math.cbrt(x) |
返回x 的立方根 |
Math.acos(x) |
返回x 的反余弦 |
Math.acosh(x) |
返回 x 的反双曲余弦 |
Math.asin(x) |
返回 x 的反正弦 |
Math.asinh(x) |
返回 x 的反双曲正弦 |
Math.atan(x) |
返回 x 的反正切 |
Math.atanh(x) |
返回 x 的反双曲正切 |
Math.atan2(y, x) |
返回 y/x 的反正切 |
Math.cos(x) |
返回 x 的余弦 |
Math.sin(x) |
返回 x 的正弦 |
Math.tan(x) |
返回x 的正切 |
eval() 方法
该就是一个完整的ECMAScript
解释器,它接收一个参数,即一个要执行的ECMAScript(JavaScript)
字符串。
eval("console.log('hi')");
// 等价于
console.log("hi");
当解释器发现eval()
调用时,会将参数解释为实际的ECMAScript
语句,然后将其插入到该位置。
通过eval()
执行的代码属于该调用所在上下文,被执行的代码与该上下文拥有相同的作用域链。
let msg = "hello world";
eval("console.log(msg)"); // "hello world"
<br />在`eval()`内部定义一个函数或变量,然后在外部代码中引用。
eval("function sayHi() { console.log('hi'); }");
sayHi();
<br />对于变量也是一样的。
eval("let msg = 'hello world';");
console.log(msg);
// Reference Error: msg is not defined
通过eval()
定义的任何变量和函数都不会被提升,这是因为在解析代码的时候,它们是被包含在一个字符串中的。它们只是在eval()
执行的时候才会被创建。
最后
Global
对象有很多属性,像undefined
、NaN
和Infinity
等特殊值都是Global
对象的属性。此外,所有原生引用类型构造函数,比如Object
和Function
,也都是Global
对象的属性。