ES6-内置对象类型的扩展(一)
字符串的扩展
新增方法
确定包含关系
includes()
: 返回布尔值,表示是否找到了参数字符串,支持第二个参数,表示开始搜索的位置1
2'hello world'.includes('llo') // => true
'hello world'.includes('llo', 5) // => falsestartsWith()
: 返回布尔值,表示参数字符串是否在原字符串的头部,支持第二个参数,表示开始搜索的位置1
2'hello world'.startsWith('llo') // => false
'hello world'.startsWith('llo', 2) // => trueendsWith()
: 返回布尔值,表示参数字符串是否在原字符串的尾部,支持第二个参数,表示开始搜索的位置1
2'hello world'.endsWith('llo') // => true
'hello world'.endsWith('llo', 2) // => true
重复
repeat()
方法返回一个新的字符串,表示将原字符串重复n次
1 | 'abcd'.repeat(3) // => abcdabcdabcd |
如果参数是小数,则先取整,取整后为负数或者Infinity
则报错;参数为字符串则先转换为数字;NaN
视为0
字符串补全
ES2017引入了字符串长度补全方法,padStart()
用于头部补全,padEnd()
用于尾部补全。
这两个方法可以接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串
可以用于提示字符串格式
1 | '04-26'.padStart(10, 'YYYY-MM-DD') // => YYYY-04-26 |
如果原字符串的长度等于或大于最大长度,则字符串补全不生效,返回原字符串
1
2'abcd'.padStart(2, 'efg') // => abcd
'abcd'.padEnd(2, 'efg') // => abcd如果用来补全的字符串与原字符串,两者的长度之和超过了最大长度,则会截去超出位数的补全字符串
1
2'abcd'.padStart(6, 'efgh') // => efabcd
'abcd'.padEnd(6, 'efgh') // => abcdef如果省略第二个参数,默认使用空格补全长度
1
2'abcd'.padStart(6) // => ' abcd'
'abcd'.padEnd(6) // => 'abcd '
数值的扩展
二进制和八进制表示
ES6中二进制和八进制分别用前缀0b
(或0B
)和0o
(或0O
)表示
1 | 0b1101 === 13 // => true |
可以使用Number()
方法将0b
和0o
前缀的数值转为十进制
1 | Number(0b1101) // => 13 |
Number对象上的新方法
Number.isFinite()
用来检查一个数值是否是有限的,仅对数值有效,对于非数值一律返回false
1
2Number.isFinite(3.14) // => true
Number.isFinite(Infinity) // => falseES5部署方法:
1
2
3
4
5
6
7
8
9
10
11
12
13(function (global) {
var global_isFinite = global.isFinite;
Object.defineProperty(Number, 'isFinite', {
value: function isFinite(value) {
return typeof value === 'number' && global_isFinite(value);
},
configurable: true,
enumerable: false,
writable: true
});
})(this);Number.isNaN()
用来检查一个数值是否为NaN
,仅对NaN
返回true
,对于其他一律返回false
1
2Number.isNaN(NaN) // => true
Number.isNaN(3.14) // => falseES5部署方法:
1
2
3
4
5
6
7
8
9
10
11
12
13(function (global) {
var global_isNaN = global.isNaN;
Object.defineProperty(Number, 'isNaN', {
value: function isNaN(value) {
return typeof value === 'number' && global_isNaN(value);
},
configurable: true,
enumerable: false,
writable: true
});
})(this);ES6将全局方法
parseInt()
和parseFloat()
移植到Number对象上面,行为完全保持不变,目的是逐步减少全局性方法,使得语言逐步模块化Number.isInteger()
用来判断一个值是否为整数1
2Number.isInteger(3.0) // => true
Number.isInteger('3.0') // => falseES5部署方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14(function (global) {
var floor = Math.floor,
isFinite = global.isFinite;
Object.defineProperty(Number, 'isInteger', {
value: function isInteger(value) {
return typeof value === 'number' && isFinite(value) && (floor(value) === value);
},
configurable: true,
enumerable: false,
writable: true
});
})(this);JavaScript中整数和浮点数用同样的存储方法,3.0和3被视为同一个值
Number.EPILSON
是ES6在Number
对象上新增的一个极小的常量1
Number.EPILSON // => 2.220446049250313e-16
引入该常量的目的:为浮点数计算设置误差范围
安全整数
JavaScript能表示的整数范围在-253到253之间
1
Math.pow(2, 53) === Math.pow(2, 53) + 1 // => true
ES6引入
Number.MAX_SAFE_INTEGER
和Number.MIN_SAFE_INTEGER
表示证书范围的上下界1
2
3Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1 // => true
Number.MAX_SAFE_INTEGER === Math.pow(2, 53) // => false
Number.MAX_SAFE_INTEGER === -Number.MIN_SAFE_INTEGER // => trueNumber.isSafeInteger()
用来判断一个整数是否在这个范围1
2Number.isSafeInteger(3) // => true
Number.isSafeInteger('a') // => false函数实现:
1
2
3
4
5
6Number.isSafeInteger = function (n) {
return typeof n === 'number' &&
Math.round(n) === n &&
Number.MIN_SAFE_INTEGER <= n &&
Number.MAX_SAFE_INTEGER >= n;
}使用时应验证参与运算的每个值,只验证结果可能会发生错误
1
2
3
4
5
6Number.isSafeInteger(9007199254740993) // => false
Number.isSafeInteger(990) // => true
Number.isSafeInteger(9007199254740993 - 990) // => true
// 9007199254740993 - 990
// 返回结果 9007199254740002
// 正确答案应该是 9007199254740003可以使用以下函数
1
2
3
4
5
6function trusty(left, right, result) {
if (Number.isSafeInteger(left) && Number.isSafeInteger(right) && Number.isSafeInteger(result)) {
return result;
}
throw new RangeError('Operation cannot be trusted');
}
Math对象上的扩展
所有方法均为静态方法,只能在Math
对象上调用
Math.trunc()
用于去除一个数的小数部分;对于数字字符串,先转换为数字;对于空值和无法截取的值,返回NaN
1
2
3
4
5
6
7Math.trunc(3.14) // => 3
Math.trunc(-3.14) // => -3
Math.trunc(-0.14) // => -0
---------------------------------------------
Math.trunc('3.14') // => 3
---------------------------------------------
Math.trunc('abd') // => NaN对于没有部署该方法的环境:
1
2
3
4
5
6
7
8Math.trunc = Math.trunc || function (x) {
return x < 0 ? Math.ceil(x) : Math.floor(x);
}
-----------------------------------------------
Math.trunc = Math.trunc || function(x) {
x = +x;
return (x - x % 1) || (!isFinite(x) || x === 0 ? x : x < 0 ? -0 : 0);
};Math.sign()
用来判断一个数是正数,负数,还是0;对于非数值,会先将其转换为数值,否则返回NaN
1
2
3
4
5
6
7
8
9Math.sign(3.14) // => 1
Math.sign(-3.14) // => -1
-----------------------------------------
Math.sign('3.14') // => 1
-----------------------------------------
Math.sign(0) // => 0
Math.sign(-0) // => -0
-----------------------------------------
Math.sign('abc') // => NaN对于没有部署该方法的环境:
1
2
3
4
5
6
7Math.sign = Math.sign || function (x) {
x = +x; // 转换为数字
if (x === 0 || isNaN(x)) {
return x;
}
return x > 0 ? 1 : -1;
}Math.cbtr()
用于计算一个数的立方根;对于非数值,会先将其转换为数值,否则返回NaN
1
2
3
4Math.cbrt(-8) // => -2
-----------------------------------------
Math.cbrt('8') // => 2
Math.cbrt('asd') // => NaN对于没有部署该方法的环境:
1
2
3
4Math.cbrt = Math.cbrt || function (x) {
var y = Math.pow(Math.abs(x), 1 / 3);
return x < 0 ? -y : y;
}Math.clz32()
用于返回一个数的32位无符号整数形式有多少个前导0;对于小数,只考虑整数部分;对于非数值,会先将其转换为数值,然后在计算1
2
3
4
5
6
7Math.clz32(1000) // => 22
Math.clz32(0b1000) // => 28
Math.clz32(3.14) // => 30
-----------------------------------------
Math.clz32('asd') // => 32
-----------------------------------------
Math.clz32(true) // => 31对于没有部署该方法的环境:
1
2
3
4
5
6
7
8
9
10
11
12
13
14Math.clz32 = Math.clz32 || function(value) {
var value = Number(value) >>> 0;
return value ? 32 - value.toString(2).length : 32;
}
-------------------------------------------------------
// 另一种实现方法
Math.clz32 = (function(log, LN2){
return function(x) {
if (x == null || x === 0) {
return 32;
}
return 31 - (log(x >>> 0) / LN2 | 0);
};
})(Math.log, Math.LN2);Math.imul()
方法返回两个数以32位带符号整数形式相乘的结果;对于大数的乘法可以返回正确的低位数值Math.fround()
返回最接近的32位单精度浮点数形式;对于整数结果没有不同1
2Math.fround(1) // => 1
Math.fround(1.23) // => 1.2300000190734863对于没有部署该方法的环境:
1
2
3
4
5Math.fround = Math.fround || (function (array) {
return function(x) {
return array[0] = x, array[0];
};
})(new Float32Array(1));Math.hypot()
返回所有参数平方和的平方根;对于非数值,会先将其转换为数值,否则返回NaN
1
2
3
4Math.hypot(3, 4) // => 5
Math.hypot(3, 4, 5) // => 7.0710678118654755
Math.hypot() // => 0
Math.hypot('a', 'b') // => NaN对于没有部署该方法的环境:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28Math.hypot = Math.hypot || function() {
var y = 0,
i = arguments.length;
while (i--) {
y += arguments[i] * arguments[i];
}
return Math.sqrt(y);
};
// 该方法有一个问题:
// 在JS的双浮点数中可以表示的最大数字是number.max_value=1.797e+308
// 如果你的数字大于1E154,取它们的平方将导致无穷大,从而破坏结果
// 例如,math.sqrt(1e200*1e200+1e200*1e200)=infinity
// 可以使用以下方法避免数字溢出或下溢
Math.hypot = function (x, y) {
var max = 0;
var s = 0;
for (var i = 0; i < arguments.length; i += 1) {
var arg = Math.abs(Number(arguments[i]));
if (arg > max) {
s *= (max / arg) * (max / arg);
max = arg;
}
s += arg === 0 && max === 0 ? 0 : (arg / max) * (arg / max);
}
return max === 1 / 0 ? 1 / 0 : max * Math.sqrt(s);
};对数方法
Math.expm1()
返回 ex - 1,即Math.exp(x) - 1
1
2Math.expm1(1) // => 1.718281828459045
Math.expm1(0) // => 0对于没有部署该方法的环境:
1
2
3Math.expm1 = Math.expm1 || function(x) {
return Math.exp(x) - 1;
};Math.log1p(x)
返回 ln(1 + x),即Math.log(1 + x)
;如果x小于-1,则返回NaN
1
2
3
4Math.log1p(1) // => 0.6931471805599453
Math.log1p(0) // => 0
Math.log1p(-1) // => -Infinity
Math.log1p(-2) // => NaN对于没有部署该方法的环境:
1
2
3Math.log1p = Math.log1p || function(x) {
return Math.log(1 + x);
};Math.log10(x)
返回以10为底的x的对数;如果x小于0,则返回NaN
1
2
3
4Math.log10(1000) // => 3
Math.log10(1) // => 0
Math.log10(0) // => -Infinity
Math.log10(-2) // => NaN对于没有部署该方法的环境:
1
2
3Math.log10 = Math.log10 || function(x) {
return Math.log(x) / Math.LN10;
};Math.log2(x)
返回以10为底的x的对数;如果x小于0,则返回NaN
1
2
3
4Math.log2(8) // => 3
Math.log2(1) // => 0
Math.log2(0) // => -Infinity
Math.log2(-2) // => NaN对于没有部署该方法的环境:
1
2
3Math.log2 = Math.log2 || function(x) {
return Math.log(x) / Math.LN2;
};
双曲函数方法
Math.sinh(x)
返回x的双曲正弦Math.cosh(x)
返回x的双曲余弦Math.tanh(x)
返回x的双曲正切Math.asinh(x)
返回x的反双曲正弦Math.acosh(x)
返回x的反双曲余弦Math.atanh(x)
返回x的反双曲正切
指数运算符
ES2016新增了指数运算符
**
,可以与等号结合为**=
1
2
3
42 ** 3 // => 8
----------------------------------------
let a = 3;
a **= 2; // => 9