ES6随记(2019-12)
const iotVmsMainDriverIdArr = mainPersonnelList.filter(v => v.name === payload.mainDriver);
const iotVmsMainDriverId = iotVmsMainDriverIdArr.length === 1 ? iotVmsMainDriverIdArr[0]['iotVmsPersonnelId'] : '';
一、let 和 const 命令
let 特性:
- 用来声明变量,只在它所在的代码块中有效,所以在此块级作用域中不可重复声明;
- 不存在变量提升,声明后必须使用;
- 块级作用域中未声明就是用会报错(暂时性死区);
// var 存在变量提升,undefined是一种数据类型
console.log(foo); // 输出undefined
var foo = 2;
// let 不声明就使用会报错
console.log(bar); // 报错ReferenceError
let bar = 2;
const 特性:
- 具有上面 let 的三个特性;
- 声明后所指向的内存地址不会变动: 声明的简单类型的数据(数值、字符串、布尔值)等同于常量,复合类型的数据(比如对象、数组)只保存指针,原数据的数据结构是不是可变的,不能控制;
const a = {value:1}
a.value = 2
console.log(a) //{value:2}
const b =[1,2,3]
b.push(4)
console.log(b) //[1,2,3,4]
ES6 声明变量的六种方法:
ES5只有两种:var命令和function命令。ES6添加了let和const命令,以及import命令和class命令。
二、解构赋值
ES6 允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
1.数组的解构
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined 解构不成功,变量的值就等于undefined。
z // []
2.对象的解构
解构对象时变量名与属性同名才能取到正确的值;
let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined
当然变量名与属性名不一致时,可以这样写:
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
对象的解构赋值的内部机制是先找到同名属性,然后在赋给对应的变量,所以,真正被赋值的是后者而不是前者。对象可以嵌套解构,可以指定默认值;其他类型也可以解构赋值,这里就不一一说明了。
3.解构赋值的部分使用场景
交换变量的值:
let x = 1;
let y = 2;
[x, y] = [y, x];
提取 JSON 数据:
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
遍历 Map 结构:
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}
// first is hello
// second is world
// 获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
}
三、数据类型的扩展
1.字符串的扩展
字符串的扩展有很多,写一下我认为能用到的几点:
ES6为字符串添加了遍历器接口(详见《Iterator》),让字符串可以被for···of循环遍历。
for (let codePoint of 'foo') {
console.log(codePoint)
}
// "f"
// "o"
// "o"
实例方法:includes(), startsWith(), endsWith()
传统上,JavaScript只有indexOf方法可以用来确定一个字符串是否包含在另一个字符串中。现在,ES6又提供了三种新的方法:
- includes():返回布尔值,表示是否找到参数字符串。
- startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
- endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
这三种方法都支持第二个参数,表示开始搜索的位置。
let s = 'Hello world!';
s.startsWith('Hello') // true ;表示参数字符串是否在原字符串的尾部
s.endsWith('!') // true ;表示参数字符串是否在原字符串的头部
s.includes('o') // true ;是否找到参数字符串
实例方法:repeat()
repeat 方法返回一个新字符串,表示将原字符串重复n次。参数如果是小数则取整,不能小于等于-1,-1(不包含)到1(不包含)视同为0,NAN也是一样,数字型的字符串会自动转换,不是则为“”;
'hello'.repeat(2) // "hellohello"
实例方法:padStart(),padEnd()
padStart()用于头部补全,padEnd()用于尾部补全。第一个参数是字符串补全生效的最大长度,第二个参数是用来补全的字符串。
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4) // ' x',第二个参数不填表示为空格
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12" //用来提示字符串格式
实例方法:trimStart(),trimEnd()
trimStart()消除字符串头部的空格,trimEnd()消除尾部的空格。它们返回的都是新字符串,不会修改原始字符串。
const s = ' abc ';
s.trim() // "abc"
s.trimStart() // "abc "
s.trimEnd() // " abc"
实例方法:matchAll()
matchAll()方法返回一个正则表达式在当前字符串的所有匹配,详见《正则的扩展》的一章。
还有一个很重要的扩展。模板字符串的写法:用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量,变量名卸载${}之中,或者也可以调用函数,也可以嵌套模板。
function authorize(user, action) {
if (!user.hasPrivilege(action)) {
throw new Error(
// 传统写法为
// 'User '
// + user.name
// + ' is not authorized to do '
// + action
// + '.'
`User ${user.name} is not authorized to do ${action}.`);
}
}