赞
踩
JavaScript
是世界上发展最快的编程语言之一,不仅可以用于编写运行在浏览器的客户端程序,随着Node.js
的发展,JavaScript
也被广泛应用于编写服务端程序。而随着JavaScript
这门语言的不断发展和完善,在2015
年正式发布的ECMAScript6
已经成为了JavaScript
这门语言的下一代标准,使得JavaScript
用来编写复杂的大型应用程序更加的得心应手。近几年几乎所有使用JavaScript
这门语言开发的项目,都在使用ES
的新特性来开发。
随着ES2015
的发布,标准委员会决定在每年都会发布一个ES
的新版本。但很多开发者并没有真正的理解ES2015+
每个版本都具有哪些新特性,以及这些新特性与ES5
语法的差别,更不清楚这些新特性在实际项目中的应用场景是怎么样的。
由于篇幅原因笔者将ES6~ES12
分成了ES大神之路一和ES大神之路二两篇文章,如果对ES6
还不是很清楚了可以先看ES大神之路一(ES6)
我相信只要你们认真看完了笔者的ES
系列文章,你一定会成为ES
大神。
接下来我们来看看ES7-ES12
吧。篇幅有点长,建议收藏后再看,后期也可以当做字典查阅。
在 ES7
之前想判断数组中是否包含一个元素,基本可以这样写:
console.log(array1.find(function(item) {
return item === 2
}))
或者
console.log(array1.findIndex(function(item) {
return item === 2
}))
或者
console.log(array1.indexOf(2) > -1)
或者
console.log(array1.filter(function(item) {
return item === 2
}).length > 0)
ES7
引入的Array.prototype.includes()
方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true
,否则返回false
。
const arr = ['es6', 'es7', 'es8']
console.log(arr.includes('es6')) // true
console.log(arr.includes('es9')) // false
includes
方法接收俩个参数,要搜索的值和搜索的开始索引。第二个参数可选。从该索引处开始查找 searchElement
。如果为负值,则从末尾第几个开始查找。
const arr = ['es6', 'es7', 'es8']
console.log(arr.includes('es7', 1)) // true
console.log(arr.includes('es7', 2)) // false
console.log(arr.includes('es7', -1)) // false
console.log(arr.includes('es7', -2)) // true
与indexOf()
比较
indexOf
返回的不是boolean
值,而是下标或-1。['a', 'b', 'c'].includes('a') //true
['a', 'b', 'c'].indexOf('a') > -1 //true
console.log(arr.indexOf('es7')) // 1
console.log(arr.indexOf('es7') > -1) // true
includes
方法只能判断简单类型的数据,对于复杂类型的数据,比如对象类型的数组,二维数组,这些是无法判断的.const arr = [1, [2, 3], 4]
arr.includes([2, 3]) //false
arr.indexOf([2, 3]) //-1
===
的操作符来作比较的,不同之处在于:对于NaN
的处理结果不同。我们知道js
中 NaN === NaN
的结果是false
, indexOf()
也是这样处理的,但是includes()
不是这样的。const demo = [1, NaN, 2, 3]
demo.indexOf(NaN) //-1
demo.includes(NaN) //true
总结
如果只想知道某个值是否在数组中存在,而并不关心它的索引位置,建议使用includes()
。如果想获取一个值在数组中的位置,那么只能使用indexOf
方法。
如果不使用任何函数,如何实现一个数的求幂运算?
function pow(x, y) {
let res = 1
for (let i = 0; i < y; i++) {
res *= x
}
return res
}
pow(2, 10) // 1024
除了自己封装函数来实现,也可是使用 Math.pow()
来完成。
Math.pow() 函数返回基数(base)的指数(exponent)次幂。
console.log(Math.pow(2, 10)) // 1024
在 ES7
可以这样写了:
console.log(2 ** 10) // 1024
注意,幂运算符的两个*号之间不能出现空格,否则语法会报错。
在ES2017(ES8)
中引入了 async
函数,使得异步操作变得更加方便。Async/Await
的出现,被很多人认为是js
异步操作的最终且最优雅的解决方案。我们可以简单理解Async/Await = Generator + Promise
。
async
用于声明一个 function
是异步的,await
用于等待一个异步方法执行完成,只有当异步完成后才会继续往后执行。await
不是必须的并且await
只能出现在 async
函数中。
async function() {
const result = await getData()
console.log(result)
}
一个函数如果加上 async ,那么该函数就会返回一个 Promise
async function async1() {
return "1"
}
console.log(async1()) // -> Promise {<resolved>: "1"}
这种用书写同步代码的方式处理异步是不是很舒服呢。
Async/Await
没有Promise
那么多的api
,错误需要自己使用try catch
处理。
async function() {
try{
const result = await getData()
console.log(result)
} catch(e) {
console.log(e)
}
}
Async/Await
相较于Promise
的链式调用完全用书写同步代码的方式处理异步使代码分厂优雅易懂。
Async/Await
这种用书写同步代码的方式使得await
会阻塞后面代码正常运行,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性。
下面笔者使用Async/Await
和Promise
作为对比举个例子说明。
function getData() { return Promise.resolve("模拟获取后端数据"); } async function fun1() { console.log("主程序开始执行"); const result = await getData(); console.log(result); console.log("让异步代码自己去执行,不阻塞我们主程序"); } fun1(); // 主程序开始执行、模拟获取后端数据、让异步代码自己去执行,不阻塞我们主程序 async function fun2() { console.log("主程序开始执行"); getData().then((result) => { console.log(result); }); console.log("让异步代码自己去执行,不阻塞我们主程序"); } fun2(); // 主程序开始执行、让异步代码自己去执行,不阻塞我们主程序、模拟获取后端数据
从上面的例子我们可以看出使用Async/Await
的弊端,就是不管后面依不依赖异步结果,Async/Await
都一定会阻塞后面代码的执行。
Async/Await
内置执行器。 Generator
函数的执行必须靠执行器(如co
函数库),而 Async/Await
函数自带执行器。也就是说,Async/Await 函数的执行,与普通函数一模一样。
Async/Await
更好的语义。 async
和 await
,比起星号和 yield
,语义更清楚了。async
表示函数里有异步操作,await
表示紧跟在后面的表达式需要等待结果。
之前的语法如何获取对象的每一个属性值
const obj = {
name: 'randy',
age: 24
}
console.log(Object.keys(obj)) // ['name', 'age']
const res = Object.keys(obj).map(key => obj[key])
console.log(res)// ["randy", 24]
ES8
中对象扩展补充了两个静态方法,用于遍历对象:Object.values(),Object.entries()
Object.values()
返回一个数组,其元素是在对象上找到的可枚举属性值。属性的顺序与通过手动循环对象的属性值所给出的顺序相同(for...in
,但是for...in
还会遍历原型上的属性值)。
const obj = {
name: 'randy',
age: 24
}
console.log(Object.values(obj)) // ["randy", 24]
Object.entries()
方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in
循环遍历该对象
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。