1.解构赋值:
//数组赋值 (以前要一个一个写 let a=1;let b=2;let c=3;)
let [a, b, c] = [1, 2, 3];
[x,y] = [y,x] //交换值
//对象赋值取值 (以前取值要let f = obj.first;let l = obj.last;)
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
//字符串长度(以前取长度要 let s = 'hello', let len = s.length)
let {length : len} = 'hello';
len // 5
//默认值
let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null
//函数返回多个值,并赋值
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
// 函数返回返回一个对象,并赋值
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
2.字符串
//at()获取指定位置的字符
'abc'.at(0) // "a"
//判断是以什么开头/结尾 包不包括
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
//重复几次
'x'.repeat(3) // "xxx"
//自动补全 (可以用于字符串格式转换 和 补0)
'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
'1'.padStart(10, '0') // "0000000001"
//模板字符串
$('#result').append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);
3.数值
//数值是否为有限
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false
//检查一个值是否为NaN
Number.isNaN(NaN) // true
Number.isNaN(15) // false
//parseInt,parseFloat使用换了
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45
//判断一个值是否为整数
Number.isInteger(25) // true
Number.isInteger(25.0) // true
Number.isInteger(25.1) // false
//Math.trunc方法用于去除一个数的小数部分,返回整数部分
Math.trunc('123.456') // 123
Math.trunc(true) //1
Math.trunc(false) // 0
Math.trunc(null) // 0
Math.trunc(NaN); // NaN
Math.trunc('foo'); // NaN
Math.trunc(); // NaN
Math.trunc(undefined) // NaN
//指数运算符 **
2 ** 2 // 4
let a = 1.5;
a **= 2;
4.函数
//函数传参默认值
function foo({x, y = 5}) {
console.log(x, y);
}
//函数的length属性 表示函数参数的个数-有默认值参数的个数
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
//一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域
let x = 1;
function f(y = x) {
let x = 2;
console.log(y);
}
f() // 1
//rest参数
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
console.log(item);
});
}
var a = [];
push(a, 1, 2, 3)
//箭头函数
var result = values.sort((a, b) => a - b);
//箭头函数的this指向外层函数,本身没有this
// ES6
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
// ES5
function foo() {
var _this = this;
setTimeout(function () {
console.log('id:', _this.id);
}, 100);
}
//函数参数的尾逗号 允许
5.数组
(1)扩展运算符 … ,将一个数组转为用逗号分隔的参数序列
console.log(...[1, 2, 3]) // 1 2 3
console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5
//扩展运算符(...)也会将空位转为undefined
[...['a',,'b']]
// [ "a", undefined, "b" ]
(2)用途
- 取代apply将参数数组转化成单一的
// ES5 的写法
Math.max.apply(null, [14, 3, 77])
// ES6 的写法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);
- 复制数组
//ES5 只能复制数组的指针,对新数组的改动会显示在旧数组里
const a1 = [1, 2];
const a2 = a1;
//ES5 或者concat 修改a2就不会对a1产生影响
const a1 = [1, 2];
const a2 = a1.concat();
a2[0] = 2;
a1 // [1, 2]
//ES6
const a1 = [1, 2];
const a2 = [...a1];
const [...a2] = a1;
- 合并数组
// ES5的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
- 字符串转化为数组
[...'hello'] // [ "h", "e", "l", "l", "o" ]
- Array.from() –任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换。
Array.from({ length: 3 });
// [ undefined, undefined, undefined ]
Array.from([1, 2, 3], (x) => x * x)
//Array.from方法会将数组的空位,转为undefined
Array.from(['a',,'b'])
// [ "a", undefined, "b" ]
- Array.of方法用于将一组值,转换为数组。
- copyWithin()
// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]
//copyWithin()会连空位一起拷贝。
[,'a','b',,].copyWithin(2,0) // [,"a",,"a"]
- find() 和 findIndex()
[1, 4, -5, 10].find((n) => n < 0)
// -5
//可以发现NaN,弥补了数组的indexOf方法的不足
[NaN].indexOf(NaN)
// -1
[NaN].findIndex(y => Object.is(NaN, y))
// 0
- fill()
['a', 'b', 'c'].fill(7, 1, 2)
- includes()
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[NaN].indexOf(NaN)
[NaN].includes(NaN)
6.对象
//绝对相等
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
//Object.assign() 复制对象 多个源对象有同名属性,则后面的属性会覆盖前面的属性。
const target = { a: 1,b: 1 };
const source1 = { b: 2,c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
Object.assign(obj, undefined) === obj // true
Object.assign(obj, null) === obj // true
//Object.keys()遍历参数对象的键名 供for...of循环使用。 代替for...in
let obj = { a: 1, b: 2, c: 3 };
for (let key of Object.keys(obj)) {
console.log(key); // 'a', 'b', 'c'
}
for (let value of Object.values(obj)) {
console.log(value); // 1, 2, 3
}
for (let [key, value] of Object,entries(obj)) {
console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}
//扩展运算符 取出参数对象的所有可遍历属性,拷贝到当前对象之中
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }
//null传导运算符
//es5
const firstName = (message
&& message.body
&& message.body.user
&& message.body.user.firstName) || 'default';
//es6
const firstName = message?.body?.user?.firstName || 'default';
7.symbol
Symbol.isConcatSpreadable属性等于一个布尔值,表示该数组或对象用于Array.prototype.concat()时,是否可以展开。
let arr1 = ['c', 'd'];
['a', 'b'].concat(arr1, 'e') // ['a', 'b', 'c', 'd', 'e']
arr1[Symbol.isConcatSpreadable] // undefined
let arr2 = ['c', 'd'];
arr2[Symbol.isConcatSpreadable] = false;
['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']
let obj = {length: 2, 0: 'c', 1: 'd'};
['a', 'b'].concat(obj, 'e') // ['a', 'b', obj, 'e']
obj[Symbol.isConcatSpreadable] = true;
['a', 'b'].concat(obj, 'e') // ['a', 'b', 'c', 'd', 'e']
8.Set 类似数组,成员唯一
- add(value):添加某个值,返回 Set 结构本身。
- delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
- has(value):返回一个布尔值,表示该值是否为Set的成员。
- clear():清除所有成员,没有返回值。
(1)去除重复元素
[...new Set(array)]
Array.from(new Set(array))
(2)遍历
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.values()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.entries()) {
console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
set.forEach((value, key) => console.log(key + ' : ' + value))
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
(3)配合…. 和 array.from 可以使用filter map
let set = new Set([1, 2, 3]);
set = new Set([...set].map(val => val * 2));
let set = new Set([1, 2, 3, 4, 5]);
set = new Set([...set].filter(x => (x % 2) == 0));
9.Map –类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
- size const map =new Map(); map.size;
- set map.set(‘foo’, true)
- get map.get(‘foo’)
- has map.has(‘foo’) //true
- delete map.delete(‘foo’) //true
- clear map.clear()
//Map转为数组
const myMap = new Map()
.set(true, 7)
.set({foo: 3}, ['abc']);
[...myMap] // [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
//数组转为Map
new Map([
[true, 7],
[{foo: 3}, ['abc']]
])
//Map转为对象
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
const myMap = new Map()
.set('yes', true)
.set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }
//对象转为Map
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
objToStrMap({yes: true, no: false})
// Map {"yes" => true, "no" => false}
//Map 转为 JSON
function strMapToJson(strMap) {
return JSON.stringify(strMapToObj(strMap));
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'
//JSON 转为 Map
function mapToArrayJson(map) {
return JSON.stringify([...map]);
}
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'
//JSON 转为 Map
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"yes": true, "no": false}')
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}