ES6用法整理
let 和 const
ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
const声明一个只读的常量。一旦声明,常量的值就不能改变。
扩展运算符(…)
扩展运算符(spread)是三个点(…)
console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]
Set 和 Map
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
console.log(i);
}
// 2 3 5 4
// 例一
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]
// 例二
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5
// 例三
const set = new Set(document.querySelectorAll('div'));
set.size // 56
// 类似于
const set = new Set();
document
.querySelectorAll('div')
.forEach(div => set.add(div));
set.size // 56
Promise
Promise对象是一个构造函数,用来生成Promise实例.
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function() {
console.log('resolved.');
});
Proxy 和 Reflect
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
var obj = new Proxy({}, {
get: function (target, key, receiver) {
console.log(`getting ${key}!`);
return Reflect.get(target, key, receiver);
},
set: function (target, key, value, receiver) {
console.log(`setting ${key}!`);
return Reflect.set(target, key, value, receiver);
}
});
Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API
Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。
Proxy(target, {
set: function(target, name, value, receiver) {
var success = Reflect.set(target,name, value, receiver);
if (success) {
console.log('property ' + name + ' on ' + target + ' set to ' + value);
}
return success;
}
});
Generator函数 和 async 函数
Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
async 函数是什么?一句话,它就是 Generator 函数的语法糖。
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
async function f() {
try {
await Promise.reject('出错了');
} catch(e) {
}
return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v))
// hello world
Class类
JavaScript 语言中,生成实例对象的传统方法是通过构造函数
//传统方法
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);
ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
//class用法
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
解构赋值
//class用法
const obj = {
a:1,
b:2,
c:3,
d:4,
e:5,
}
// 注意解构的对象不能为undefined、null。否则会报错
const {a:a1,b,c,d,e} = obj || {};
console.log(a1, b,c,d,e) // 1,2,3,4,5
拼接字符串
const name = '大白';
const score = 59;
const result = `${name}的考试成绩${score > 60?'':'不'}及格`;
includes方法使用
const condition = [1,2,3,4];
if( condition.includes(type) ){
//...
}
find方法使用
find方法中找到符合条件的项,就不会继续遍历数组
const a = [1,2,3,4,5];
const result = a.find(
item =>{
return item === 3
}
)
扁平化数组flat()
const obj = {
item1: [1,2,3],
item2: [4,5,6],
item3: [7,[8, [9,10]]]
}
//其中使用Infinity作为flat的参数,使得无需知道被扁平化的数组的维度
let member = Object.values(obj).flat(Infinity) // 1,2,3,4,5,6,7,8,9,10
获取对象属性值(可选链操作符)
const obj = { name: 'cc' }
//原来的方法
// &&运算符 都为真则返回最后一个值,若有一个 非真则返回false
//const name = obj && obj.name; //cc
const name = obj?.name; // cc
空值合并运算符
空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。
//原判断
if(value !== null && value !== undefined && value !== ''){
//...
}
//合并运算符 优化后
if((value??'') !== ''){
//...
}