let const var
let 对定义的变量形成块级作用域,不存在变量提升,定义的变量需要声明后才可使用,定义后的变量不 可再重复定义
const 定义后的变量 不可再重复定义
var 不会形成作用域,会形成变量提升,可以定义全局变量,也可定义局部变量,
解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
[a,b]=[1,2];console.log(a,b)//1 2;
[a,b]=[{},2];console.log(a,b)//{} 2;
[a]=[{},2];console.log(a);//{},2;
[a,b]=[2];console.log(a,b)//2 undefined
对字符串的解构赋值
[a,b,c,…d]=‘hello’;console.log(a,b,c,d)//h e l [“l”,“o”]
对数组的解构赋值
([1,2],[3,4]).map((a,b)=>a+b);//[3,5]
字符串新增
模板字符串 ``
模板字符串中嵌入变量,需要将变量名写在${}之中。
var a=1;var b=3;`${a+b}`;//"4"
字符串新增方法
repeat()
返回一个新字符串,表示将原字符串重复n次。
'hello'.repeat(2);//'hellohello'
padStart(number[,string]);string若是不写则默认加 空格
如果某个字符串不够指定长度,会在头部补全
"nihao".padStart(8);//" nihao"
"nihao".padStart(8,"dc");//"dcdnihao"
padEnd() 尾部补全
trimStart() 去除头部空格(左边空格)
trimEnd() 去除尾部空格(右边空格)
replace()替换
"hhhha".replace('h',4);//"4hhha"
"hhhha".replace(/h/g,4);//"4444a"
replaceAll()全部替换
"hhhha".replaceAll('h',4);//"4hhha"
函数
箭头函数
function tt(a,b){return a+b};tt(1,2)//3
var tt=(a,b)=>a+b;tt(1,2);//3
作用域
var x=1;
var tt=(x,y=x)=>console.log(y);tt()//undefined
var x=1;
var tt=(x,y=x)=>console.log(y);tt(2);//2
数组
扩展运算符 ...
将数组转为用逗号分隔的参数序列
var arr=[1,3,2];
console.log(...arr);//1,2,3;
function d(a,b,c){return a+b+c};
d(...arr);
console.log(d);//6
...
后面还可以跟表达式
var x =1 ;var arr = [
...(x > 0 ? ['a'] : []),
'b',
];console.log(arr)
求一个数组的最大元素
Math.max(...[1,2,3]);
将一个数组的元素添加到另一数组中
var a=[1,2];var b=[3,4];a.push(...b);console.log(a)//[1, 2, 3, 4]
合并数组
[...a,...b];
复制数组(即创建一个新数组的同时,不会对原数组产生影响)
const a1=[1,2];const a2=[...a1];console.log(a1,a2);
const a1=[1,2];const [...a2]=a1;console.log(a2);
与解构赋值结合
[a,...[]]=list
var a='';var b=[]; [a,...b]=[1,2,3,4,4];console.log(a,b)//1 [2,3,4,4]
var a='';var b=[];[a,...b]=[];a,b//undefined [];
将字符串转为数组
[...'1234'];//["1", "2", "3", "4"]
Map结构转为数组
var map = new Map([ [1, 'one'],[2, 'two'],[3, 'three'],]);
var arr = [...map.values()];arr;//["one", "two", "three"]
将类似与数组的结构转为数组
所谓类似数组的对象,本质特征只有一点,即必须有length属性。因此,任何有length属性的对象,都可以通过Array.from方法转为数组
var arrayLike = {'0': 'a','1': 'b','2': 'c',length: 3};
var arr=Array.from(arrayLike)console.log(arr)//["a", "b", "c"]
Array.from('123');//["1", "2", "3"]
Array.of()将一组值转为数组
Array.of(1,2,3);//[1,2,3]
查找符合条件的元素 find()
[1,2,3].find(d=>d>2)//3
查找符合条件的元素下标 findIndex()
[1,2,3].findIndex(d=>d>2)//2
接受第二个参数,用来绑定回调函数的this对象
var dd={name:'aa',age:'14'};[23,13,65].find(function(p){return this.age>p},dd);//13
数组的entries(),keys(),values()
for(var d of [1,2,3].values()){console.log(d)};//1,2,3
for(var d of [1,2,3].keys()){console.log(d)};//0,1,2
for(var d of [1,2,3].entries()){console.log(d)};//[0,1] [1,2] [2,3]
flat(),将嵌套的数组拉平,变成一维数组,返回新数组,对原数组没有影响
[1,2,[2,3]].flat()//[1, 2, 2, 3]
flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数
[1, 2, [3, [4, 5]]].flat()// [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2)// [1, 2, 3, 4, 5]
[1, [2, [3]]].flat(Infinity)//[1,2,3] //Infinity表示不管有多少维数组都转为一维数组
对象
函数的表达式更简洁
for in ,for of 遍历
引入super关键字 指向当前对象的原型对象。
const proto = {
foo: 'hello'
};
const obj = {
foo: 'world',
find() {
return super.foo;
}
};
Object.setPrototypeOf(obj, proto);
console.log(obj)//hello
const obj = {
foo: 'world',
find() {
return this.foo;
}
};console.log(obj)
VM3267:6 {foo: "world", find: ƒ}
super关键字表示原型对象时,只能用在对象的方法之中
Object.is() 等价于 === 表示严格相等
Object.assign() 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 ,b:1};
Object.assign(target, source1, source2);
target // {a:1, b:1, c:3}
Object.assign()的第一个参数是目标对象,后面的都是源对象
如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
typeof Object.assign(2);//Object
如果该参数不是对象,则会先转成对象,然后返回。
由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。
Object.assign()可以用来处理数组,但是会把数组视为对象。但是数组的属性名相同时,会发生覆盖
Object.assign([1, 2, 3], [4, 5])//[3,4,5]
可以为对象添加属性
var dd={name:'any',age:'13'};Object.assign(dd,{color:'blue'});console.log(dd);//{name: "any", age: "13", color: "blue"}
可以为对象添加方法
Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});
合并多个对象
const merge =
(target, ...sources) => Object.assign(target, ...sources);
克隆对象
function clone(origin) {
return Object.assign({}, origin);
}
运算符
指数运算符 **
,执行方式为右结合
3**3//27
2**3**2//252
新的赋值运算符**=
var a=3;a**=4;//81
var a=3;a**=4**2;//43046721
set
使用Set对数组及字符串进行去重
[...new Set([a,b,b,c,1,2,1])]//[a,b,c,1,2]
[...new Set('1b222cdd')].join('')//'1b2cd'
forEach()遍历,遍历出对象或数组中的每一项
[1,2,3].forEach(e=>{console.log(e)})//1 2 3
[{a:2},{b:2}].forEach(e=>{console.log(e)})// {a:2} {b:2}
forEach()遍历时,仅仅只是遍历,不进行逻辑的判断,会进行到底类似于for…in循环,for…of用于遍历值
[1,2,,4].forEach((e,index,array)=>console.log(`a[${index}]`))//a[0] a[1] a[3]
for(var i in [1,2,,4]){console.log(i)}//0 1 3
for(var i of [1,2,,4]){console.log(i)}// 1 2 undefined 4
filter()过滤 过滤出符合条件的值
[1,4,5].filter(e=>e>2)//[4, 5]
[1,4,5].filter(e=>e**2>10)//[4,5]
利用set实现并集、交集、差集
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));// set {2, 3}
// (a 相对于 b 的)差集
let difference = new Set([...a].filter(x => !b.has(x)));// Set {1}
将set结构转为数组
Array.from(new Set([...[1,2,3],...[2,3,4]]))//[1, 2, 3, 4]
Map
var a={b:'hh'};var m=new Map();m.set(a,'heng');m.get(a);//"heng" m.has(a);//true m.delete(a);//true m.has(a);//false m.set(a);m.clear();m.has(a)//false;
map()遍历
[{a:1},{b:2},{c:3}].map((value,index)=>value)//[{a:1},{b:2},{c:3}]
[{a:1},{b:2},{c:3}].map((value,index)=>index)//[0,1,2]
proxy 代理
额,暂时看不懂
reflect 类似于proxy
promise 对象
这个是重中之重,涉及到处理api接口
promise是异步编程的一种解决方案,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),Promise对象可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数,
Promise对象是一个构造函数,用来生成Promise实例
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
// Promise
// Hi!
// resolved
上面代码中,Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。
promise.then()
then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)
getJSON("/post/1.json").then(
post => getJSON(post.commentURL)
).then(
comments => console.log("resolved: ", comments),
err => console.log("rejected: ", err)
);
promise.catch() 用于指定发生错误时的回调函数。
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误
console.log('发生错误!', error);
});
上面代码中,getJSON()方法返回一个 Promise 对象,如果该对象状态变为resolved,则会调用then()方法指定的回调函数;如果异步操作抛出错误,状态就会变为rejected,就会调用catch()方法指定的回调函数,处理这个错误。另外,then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获。
Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获
getJSON('/post/1.json').then(function(post) {
return getJSON(post.commentURL);
}).then(function(comments) {
// some code
}).catch(function(error) {
// 处理前面三个Promise产生的错误
});
上面代码中,一共有三个 Promise 对象:一个由getJSON()产生,两个由then()产生。它们之中任何一个抛出的错误,都会被最后一个catch()捕获。
promise.finally() 用于指定不管 Promise 对象最后状态如何,都会执行的操作
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
finally本质上是then方法的特例。
promise
.finally(() => {
// 语句
});
// 等同于
promise
.then(
result => {
// 语句
return result;
},
error => {
// 语句
throw error;
}
);
promise.all() 用于将多个 Promise 实例,包装成一个新的 Promise 实例
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
})
.then(result => result)
.catch(e => e);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
async 和 await
async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖
async function timeout(ms) {
await new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value);
}
asyncPrint('hello world', 50);
async函数返回一个 Promise 对象,async函数内部return语句返回的值,会成为then方法回调函数的参数。
async function f() {return 'hello world';}
f().then(v => console.log(v))// "hello world"
Promise 对象的状态变化
async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。
async function getTitle(url) {
let response = await fetch(url);
let html = await response.text();
return html.match(/<title>([\s\S]+)<\/title>/i)[1];
}
getTitle('https://tc39.github.io/ecma262/').then(e=>console.log(e))
// "ECMAScript 2017 Language Specification"
上面代码中,函数getTitle内部有三个操作:抓取网页、取出文本、匹配页面标题。只有这三个操作全部完成,才会执行then方法
await 命令
正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值
async function f() {
// 等同于
// return 123;
return await 123;
}
f().then(v => console.log(v))// 123