ES6总结

2022-09-26 16:40:31 浏览数 (1)

书到用时方恨少啊 于是2022年的规划又多了一项:多看书 不积跬步无以至千里 不积小流无以成江海

只记录对我来说比较陌生的知识点

文章内容来自: https://es6.ruanyifeng.com/

2022 / 1 / 7

变量的解构赋值

1:变量的解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

解构赋值允许指定默认值。

代码语言:javascript复制
let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b

注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。

代码语言:javascript复制
let [x = 1] = [undefined];
x // 1

let [x = 1] = [null];
x // null

如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。

代码语言:javascript复制
function f() {
  console.log('aaa');
}

let [x = f()] = [1];

上面代码中,因为x能取到值,所以函数f根本不会执行。

2:对象的解构赋值

对象的属性没有次序,变量必须与属性同名,才能取到正确的值

如果变量名与属性名不一致,必须写成下面这样。

代码语言:javascript复制
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };

也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

默认值

默认值生效的条件是,对象的属性值严格等于undefined。

代码语言:javascript复制
var {x = 3} = {x: undefined};
x // 3

var {x = 3} = {x: null};
x // null

3:字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象 类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值

代码语言:javascript复制
let {length : len} = 'hello';
len // 5
4: 数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

代码语言:javascript复制
let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

代码语言:javascript复制
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

4:用途

从函数返回多个值

函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。

代码语言:javascript复制
// 返回一个数组

function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

函数参数的定义

解构赋值可以方便地将一组参数与变量名对应起来。

代码语言:javascript复制
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);

// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

提取 JSON 数据

解构赋值对提取 JSON 对象中的数据,尤其有用。

代码语言:javascript复制
let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]
上面代码可以快速提取 JSON 数据的值。

输入模块的指定方法

加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。

代码语言:javascript复制
const { SourceMapConsumer, SourceNode } = require("source-map");

字符串的新增方法

实例方法: includes() startsWith() endsWith()

传统上,JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6 又提供了三种新方法。

includes():返回布尔值,表示是否找到了参数字符串。 startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。 endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

代码语言:javascript复制
let s = 'Hello world!';

s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true

这三个方法都支持第二个参数,表示开始搜索的位置。

代码语言:javascript复制
let s = 'Hello world!';

s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false

上面代码表示,使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。

实例方法:repeat()

repeat方法返回一个新字符串,表示将原字符串重复n次。

代码语言:javascript复制
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""

参数如果是小数,会被取整。 如果repeat的参数是负数或者Infinity,会报错。 但是,如果参数是 0 到-1 之间的小数,则等同于 0,这是因为会先进行取整运算。0 到-1 之间的小数,取整以后等于-0,repeat视同为 0。 如果repeat的参数是字符串,则会先转换成数字。 参数NaN等同于 0。

实例方法:padStart() padEnd()

ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

代码语言:javascript复制
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'

上面代码中,padStart()和padEnd()一共接受两个参数,第一个参数是字符串补全生效的最大长度,第二个参数是用来补全的字符串。

如果原字符串的长度,等于或大于最大长度,则字符串补全不生效,返回原字符串。

代码语言:javascript复制
'xxx'.padStart(2, 'ab') // 'xxx'
'xxx'.padEnd(2, 'ab') // 'xxx'

如果用来补全的字符串与原字符串,两者的长度之和超过了最大长度,则会截去超出位数的补全字符串

代码语言:javascript复制
'abc'.padStart(10, '0123456789')
// '0123456abc'

如果省略第二个参数,默认使用空格补全长度。

代码语言:javascript复制
'x'.padStart(4) // '   x'
'x'.padEnd(4) // 'x   '

padStart()的常见用途是为数值补全指定位数。下面代码生成 10 位的数值字符串。

代码语言:javascript复制
'1'.padStart(10, '0') // "0000000001"
'12'.padStart(10, '0') // "0000000012"
'123456'.padStart(10, '0') // "0000123456"

另一个用途是提示字符串格式。

代码语言:javascript复制
'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

实例方法: trimStart() trimEnd()

ES2019 对字符串实例新增了trimStart()和trimEnd()这两个方法。它们的行为与trim()一致,trimStart()消除字符串头部的空格,trimEnd()消除尾部的空格。它们返回的都是新字符串,不会修改原始字符串。

实例方法:replaceAll()

历史上,字符串的实例方法replace()只能替换第一个匹配。

代码语言:javascript复制
'aabbcc'.replace('b', '_')
// 'aa_bcc'

上面例子中,replace()只将第一个b替换成了下划线。

如果要替换所有的匹配,不得不使用正则表达式的g修饰符。

代码语言:javascript复制
'aabbcc'.replace(/b/g, '_')
// 'aa__cc'

正则表达式毕竟不是那么方便和直观,ES2021 引入了replaceAll()方法,可以一次性替换所有匹配。

代码语言:javascript复制
'aabbcc'.replaceAll('b', '_')
// 'aa__cc'

它的用法与replace()相同,返回一个新字符串,不会改变原字符串。

实例方法 : at()

at()方法接受一个整数作为参数,返回参数指定位置的字符,支持负索引(即倒数的位置)。

代码语言:javascript复制
const str = 'hello';
str.at(1) // "e"
str.at(-1) // "o"

如果参数位置超出了字符串范围,at()返回undefined。

数值的扩展

Number.isFinite(), Number.isNaN()

ES6 在Number对象上,新提供了Number.isFinite()和Number.isNaN()两个方法。

Number.isFinite()用来检查一个数值是否为有限的(finite),即不是Infinity。

注意,如果参数类型不是数值,Number.isFinite一律返回false。

Number.isNaN()用来检查一个值是否为NaN。

代码语言:javascript复制
Number.isFinite('15'); // false
Number.isFinite(15); // true
 
Number.isNaN(NaN) // true
Number.isNaN("NaN") // false

Number.isInteger()

Number.isInteger()用来判断一个数值是否为整数。

代码语言:javascript复制
Number.isInteger(25) // true
Number.isInteger(25.1) // false

JavaScript 内部,整数和浮点数采用的是同样的储存方法,所以 25 和 25.0 被视为同一个值。

代码语言:javascript复制
Number.isInteger(25) // true
Number.isInteger(25.0) // true

如果参数不是数值,Number.isInteger返回false。

Number.EPSILON

ES6 在Number对象上面,新增一个极小的常量Number.EPSILON。根据规格,它表示 1 与大于 1 的最小浮点数之间的差。

对于 64 位浮点数来说,大于 1 的最小浮点数相当于二进制的1.00..001,小数点后面有连续 51 个零。这个值减去 1 之后,就等于 2 的 -52 次方。

Number.EPSILON实际上是 JavaScript 能够表示的最小精度。误差如果小于这个值,就可以认为已经没有意义了,即不存在误差了。

引入一个这么小的量的目的,在于为浮点数计算,设置一个误差范围。我们知道浮点数计算是不精确的。

安全整数和 Number.isSafeInteger()

JavaScript 能够准确表示的整数范围在-253到253之间(不含两个端点),超过这个范围,无法精确表示这个值。

代码语言:javascript复制
Math.pow(2, 53) // 9007199254740992

9007199254740992  // 9007199254740992
9007199254740993  // 9007199254740992

Math.pow(2, 53) === Math.pow(2, 53)   1
// true

ES6 引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。 Number.isSafeInteger()则是用来判断一个整数是否落在这个范围之内

Math对象的扩展

Math.trunc

Math.trunc方法用于去除一个数的小数部分,返回整数部分。 对于非数值,Math.trunc内部使用Number方法将其先转为数值。

Math.sign()

Math.sign方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。

它会返回五种值 参数为正数,返回 1; 参数为负数,返回-1; 参数为 0,返回0; 参数为-0,返回-0; 其他值,返回NaN。

粗体

0 人点赞