因为ES6的内容太多了, 如果想学ES6的新特性, 那么可以看 http://t.csdn.cn/1bXjB
超级全, 吐血编写
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。 使用 includes() 判断字符串和字符时是区分大小写的
语法:arr.includes(searchElement)
arr.includes(searchElement, fromIndex)
[1,2,3].includes(2); // true
[1,2,3].includes(2, 0); // true
[1,2,3].includes(2, 2); // false
[1,2,3].includes(2, 5); // false
[1,2,3].includes(2, -1); // false
该方法与indexOf()的区别在于,indexOf()不会识别NaN和稀疏数组中的缺失元素。而includes()方法可以。
var array = [1,2,3];
array.length = 5;
array.push(NaN);
array.push(undefined);
array.push("");
console.log( array.includes(undefined))// true
console.log( array.includes(NaN)) // true
console.log( array.includes("")) // true
console.log(array.indexOf(undefined))// 6
console.log(array.indexOf(NaN))// -1
console.log(array.indexOf(""))// 7
在ES7中引入了指数运算符,具有与Math.pow()求幂运算
等效的计算结果
console.log(2**10);// 输出1024
console.log(Math.pow(2, 10)) // 输出1024
我们都知道使用Promise能很好地解决回调地狱的问题,但如果处理流程比较复杂的话,那么整段代码将充斥着then,语义化不明显,代码不能很好地表示执行流程,那有没有比Promise更优雅的异步方式? ES7提出的基于Promise的解决异步的最终方案Async/Await
。
async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。因此对async修饰的函数可以直接使用then方法, 如果方法出现了异常,那么会调用catch ,注意被async修饰的方法会变为异步方法
async function fun0(){
console.log(1);
return 1;
}
fun0().then(val=>{
console.log(val) // 1,1
}).catch(err=>{
console.log(err)
})
async function fun1(){
console.log('Promise');
return new Promise(function(resolve,reject){
resolve('Promise1')
})
}
fun1().then(val => {
console.log(val); // Promise Promise
})
async function fun2(){
throw new Error("xxxxx")
}
fun2().then(val=>{
console.log(val)
}).catch(err=>{
console.log(err) //xxxxx
})
await 也是一个修饰符,只能放在async定义的函数内。可以理解为等待 , await 修饰的如果是Promise对象:可以获取Promise中返回的内容(resolve或reject的参数),且取到值后语句才会往下执行;如果不是Promise对象,比如字符串那么会把这个字符串当做await表达式的结果
使用await必须是直系(作用域链不能隔代),这样会报错:Uncaught SyntaxError: await is only valid in async function。,比如下面
let data = 'data'
demo = async function () {
const test = function () {
await data //错误使用
}
}
注意只有 let c = await new Promise ,配合才能进行等待内部执行结果,如果不是和Promise 进行配合那么await 等于无效
const demo = async ()=>{
let result = await setTimeout(()=>{
console.log('我延迟了一秒');
}, 1000)
console.log('======================');
}
demo()
// 执行结果
//======================
//我延迟了一秒
//奇怪,并没有await啊?setTimeout是异步啊,问题在哪?问题就在于setTimeout这是个异步,但是不是Promise!起不到“等待一会”的作用。
//请记住await是在等待一个Promise的异步返回
混合使用async 和await 案例
async function fun(){
let a = 1;
//内部使用了ajax会异步, 我们在外部使用await等待内部请求的结果
let b = await new Promise((resolve,reject)=>{
var ajax = new XMLHttpRequest();
ajax.open("GET", "http://localhost:7003/test/haoxiaoxiao");
ajax.setRequestHeader("Content-Type", "application/json");
ajax.send({
"userName": "卢超glrau",
"passWord": "Y2hKz0h",
"phone": "18110454396",
"email": "h.whf@gjifcniah.dk"
});
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
var json = JSON.parse(ajax.responseText);
console.log(json)
resolve(json);
}
}
})
//内部使用了setTimeout会异步, 我们在外部使用await等待setTimeout内部的结果
let c = await new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('Promise')
}, 1000)
});
let d = await function(){
return 'function'
}()
console.log(a,b,c,d)
return b;
}
fun();
const setDelay = (millisecond) => {
return new Promise((resolve, reject)=>{
if (typeof millisecond != 'number') reject(new Error('参数必须是number类型'));
setTimeout(()=> {
resolve(`我延迟了${millisecond}毫秒后输出的`)
}, millisecond)
})
}
const setDelaySecond = (seconds) => {
return new Promise((resolve, reject)=>{
if (typeof seconds != 'number' || seconds > 10) reject(new Error('参数必须是number类型,并且小于等于10'));
setTimeout(()=> {
resolve(`我延迟了${seconds}秒后输出的,注意单位是秒`)
}, seconds * 1000)
})
}
比如上面两个延时函数(写在上面),比如我想先延时1秒,在延迟2秒,再延时1秒,最后输出“完成”,这个过程,如果用then的写法,大概是这样:
setDelay(1000)
.then(result=>{
console.log(result);
return setDelaySecond(2) //注意
})
.then(result=>{
console.log(result);
return setDelay(1000) //注意
})
.then(result=>{
console.log(result);
console.log('完成')
})
.catch(err=>{
console.log(err);
})
咋一看是不是挺繁琐的?如果逻辑多了估计看得更累,现在我们来试一下async/await
(async ()=>{
const result = await setDelay(1000);
console.log(result);
console.log(await setDelaySecond(2));
console.log(await setDelay(1000));
console.log('完成了');
})()
看!是不是没有冗余的长长的链式代码,语义化也非常清楚,非常舒服,那么你看到这里,一定还发现了,上面的catch我们是不是没有在async中实现?接下去我们就分析一下async/await如何处理错误?
因为async函数返回的是一个Promise,所以我们可以在外面catch住错误。
(async ()=>{
const result = await setDelay(1000);
console.log(result);
console.log(await setDelaySecond(2));
console.log(await setDelay(1000));
console.log('完成了');
})().catch(err=>{
console.log(err)
})
// 下面这种也行
const demo = async ()=>{
const result = await setDelay(1000);
console.log(result);
console.log(await setDelaySecond(2));
console.log(await setDelay(1000));
console.log('完成了');
}
demo().catch(err=>{
console.log(err);
})
在async函数的catch中捕获错误,当做一个Pormise处理,同时你不想用这种方法,可以使用try…catch语句:
(async ()=>{
try{
const result = await setDelay(1000);
console.log(result);
console.log(await setDelaySecond(2));
console.log(await setDelay(1000));
console.log('完成了');
} catch (e) {
console.log(e); // 这里捕获错误
}
})()
这时候你就不需要在外面catch了。有人会问了,我try…catch好像只能包裹代码块,如果我需要拆分开分别处理,不想因为一个的错误就整个process都crash掉了,那么难道我要写一堆try…catch吗?我就是别扭,我就是不想写try…catch怎嘛办? 我们知道await后面跟着的肯定是一个Promise那是不是可以这样写?
(async ()=>{
const result = await setDelay(1000).catch(err=>{
console.log(err)
});
console.log(result);
const result1 = await setDelaySecond(12).catch(err=>{
console.log(err)
})
console.log(result1);
console.log(await setDelay(1000));
console.log('完成了');
})()
是不是就算有错误,也不会影响后续的操作,是不是很棒?当然不是,你说这代码也忒丑了吧,乱七八糟的,写得别扭await又跟着catch。那么我们可以改进一下,封装一下提取错误的代码函数:
function to(promise) {
return promise.then(data => {
return [null, data];
})
.catch(err => [err]); // es6的返回写法
}
// 返回的是一个数组,第一个是错误,第二个是异步结果,使用如下:
(async ()=>{
// es6的写法,返回一个数组(你可以改回es5的写法觉得不习惯的话),第一个是错误信息,第二个是then的异步返回数据,这里要注意一下重复变量声明可能导致问题(这里举例是全局,如果用let,const,请换变量名)。
[err, result] = await to(setDelay(1000))
// 如果err存在就是有错,不想继续执行就抛出错误
if (err) throw new Error('出现错误,同时我不想执行了');
console.log(result);
[err, result1] = await to(setDelaySecond(12))
// 还想执行就不要抛出错误
if (err) console.log('出现错误,同时我想继续执行', err);
console.log(result1);
console.log(await setDelay(1000));
console.log('完成了');
})()
写在async/await中想要中断程序就很简单了,因为语义化非常明显,其实就和一般的function写法一样,想要中断的时候,直接return一个值就行,null,空,false都是可以的。看例子:
let count = 6;
const demo = async ()=>{
const result = await setDelay(1000);
console.log(result);
const result1 = await setDelaySecond(count);
console.log(result1);
if (count > 5) {
return '我退出了,下面的不进行了';
// return;
// return false; // 这些写法都可以
// return null;
}
console.log(await setDelay(1000));
console.log('完成了');
};
demo().then(result=>{
console.log(result);
})
.catch(err=>{
console.log(err);
})
ES5 引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。ES8引入了跟Object.keys配套的Object.values和Object.entries,作为遍历一个对象的补充手段,供for…of循环使用。
Object.values()
//假设我们要遍历如下对象obj的所有值:
const obj = {a: 1, b: 2, c: 3};
//不使用Object.values() :ES7
const vals=Object.keys(obj).map(key=>obj[key]);
console.log(vals);//[1, 2, 3]
//使用Object.values() :ES8
const values=Object.values(obj1);
console.log(values);//[1, 2, 3]
Object.entries()
//不使用Object.entries() :ES7
Object.keys(obj).forEach(key=>{
console.log('key:'+key+' value:'+obj[key]);
})
//key:a value:1
//key:b value:2
//key:c value:3
//使用Object.entries() :ES8
for(let [key,value] of Object.entries(obj1)){
console.log(`key: ${key} value:${value}`)
}
//key:a value:1
//key:b value:2
//key:c value:3
在ES8中String 新增了两个实例函数 String.prototype.padStart 和 String.prototype.padEnd,允许将空字符串或其他字符串添加到原始字符串的开头或结尾。
ES5对String补白的方式, 例如将数字都输出成两位数,前面0补位学习
for(let i = 1 ; i < 32 ; i++){
console.log(i >= 10 ? i : `0${i}`)
}
// 1-9输出01-09
// 10-31正常输出
padStart
用另外一个字符串填充当前字符串(若是须要的话,会重复屡次),从头补白(也就是左侧)
for(let i = 1 ; i < 32 ; i++){
// 目标是2位数,不够的用0补齐
console.log(i.toString().padStart(2, '0'))
}
// 1-9输出01-09
// 10-31正常输出
padEnd
用另外一个字符串填充当前字符串(若是须要的话,会重复屡次),从当前字符串的末尾(右侧)开始填充
for(let i = 1 ; i <= 100 ; i++){
// 从尾部补充到指定的长度
console.log(i.toString().padEnd(3, 'xx'))
}
//1xx
//11x
//100
重新排列项目更简单,不必添加和删除逗号,最后的逗号了js自动处理。
//定义参数时
function foo(
param1,
param2,//结尾逗号
) {}
//传参时
foo(
'coffe',
'1891',//结尾逗号
);
//对象中
let obj = {
"a": 'coffe',
"b": '1891',//结尾逗号
};
//数组中
let arr = [
'coffe',
'1891',//结尾逗号
];
获取所有属性里面的数据描述符,只接受一个参数,目标对象。
console.log(Object.getOwnPropertyDescriptors(data))
// Portland: {value: "78/50", writable: true, enumerable: true, configurable: true}
// Dublin: {value: "88/52", writable: true, enumerable: true, configurable: true}
// Lima: {value: "58/40", writable: false, enumerable: false, configurable: true}
获取单个属性的描述符 Object.getOwnPropertyDescriptor() 这个方法接收两个参数:属性所在的对象和要读取其描述符的属性名称。
返回值是一个对象:
使用SharedArrayBuffer,两个线程的两个WebWorker都可以在同一块内存中写入数据和读取数据。这意味着它们不像postMessage那样具有通信开销和延迟。两个Web工作人员都可以立即访问到需要的数据。但是,同时从两个线程同时访问存在一定的危险。它可能导致内存中出现竞争状况。 现在游览器都禁用了SharedArrayBuffer,
Atomics 对象提供了一组静态方法用来对 SharedArrayBuffer 对象进行原子操作。
点赞 -收藏-关注-便于以后复习和收到最新内容有其他问题在评论区讨论-或者私信我-收到会在第一时间回复感谢,配合,希望我的努力对你有帮助^_^免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://huanmin.blog.csdn.net/article/details/125765544
内容来源于网络,如有侵权,请联系作者删除!