ES6 常用新特性
let && const
let 命令也用于变量声明,但是作用域为局部
1 2 3 4 5 6
| { let a =10; var b =1; }
|
在函数外部可以获取到 b,获取不到 a,因此例如for
循环计数器就适合使用 let。
const 用于声明一个常量,设定后值不会再改变
1 2 3 4 5
| const PI =3.1415; PI PI=3;
|
iterable 类型
为了统一集合类型,ES6 标准引入了新的iterable
类型,Array、Map 和 Set 都属于iterable
类型,具有
iterable
类型的集合可以通过新的 for ...of
循环来遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var a=['A','B','C']; var s=new Set(['A','B','C']); var m=new Map([[1,'x'],[2,'y'],[3,'z']]); for (var x of a){ alert(x); }
for (var x of s){ alert(x); }
for (var x of m){ alert(x[0]+'='+x[1]); }
|
Map 相关操作如下,Set 同理:
1 2 3 4 5 6 7 8
| var m = new Map(); m.set('Adam', 67); m.set('Bob', 59); m.has('Adam'); m.get('Adam'); m.delete('Adam'); m.get('Adam');
|
解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。
例如数组:
1 2 3 4 5 6 7 8 9
| let [a,b,c]=[1,2,3];
等同于
let a=1; let b=2; let c=3;
|
对象的解构赋值:获取对象的多个属性并且使用一条语句将它们赋给多个变量
1 2 3 4 5 6 7 8 9 10 11 12 13
|
var { StyleSheet, Text, View } = React;
等同于 var StyleSheet = React.StyleSheet; var Text = React.Text; var View = React.Text;
|
=>函数(箭头函数)
var sum =(num1,num2)=>{return num1+num2;}
等同于
1 2 3 4 5
| var sum =function(num1,num2){ return num1+num2; }
|
箭头函数还修复了 this 的指向,使其永远指向词法作用域:
1 2 3 4 5 6 7 8 9 10 11
| var obj = { birth: 1999, getAge: function () { var b = this.birth var fn = () => new Date().getFullYear() - this.birth return fn() } } console.log( obj.getAge())
|
…操作符
这个的引入几乎不会用到 extend 这个函数来。通过它可以将数组作为参数直接传入函数:
1 2 3 4 5
| var people = ['jack', 'Mary', 'Candy'] function sayHello(...people) { console.log(`Hello ${people}!`) } sayHello(people)
|
在函数定义时可以通过…rest 获取定义 参数外 的所有参数
1 2 3 4 5 6 7 8 9 10
| function foo(a, b, ...rest) { console.log('a=' + a) console.log('b=' + b) console.log(rest) } foo(1, 2, 3, 4, 5)
|
类
ES6 提供了更接近 传统语言的写法,引入了 Class (类) 这个概念,作为对象的模板。
1 2 3 4 5 6 7 8 9 10 11 12 13
|
class Point { constructor(x, y) { this.x = x this.y = y }
toString() { return '(' + this.x + ',' + this.y + ')' } }
|
ES7 常用新特性
Array.prototype.includes (includes)
Array.prototype.includes
是替代indexOf
,开发人员用来检查数组中是否存在值,indexOf
是一种尴尬的使用,因为它返回一个元素在数组的位置或者-1(当这样的元素不能被找到的情况下)。
所以它返回的是一个数字 ,而不是一个 布尔值。
开发人员需要实施额外的检查。在 ES6,要检查是否存在值需要做如下图所示小技巧,因为他们没有匹配到值,Array.prototype.includes
返回-1 变成 true,但是当匹配的元素为 0 位置的时候,该数组包含元素,却变成 false。
1 2 3 4 5
| let arr = ['react', 'angular', 'vue']
console.log(arr.indexOf('react'))
|
或者使用一点点 hack 位运算符 ~ 使代码更加紧凑一些 ,因为 ~(位异或)对任何数字相当于 -(a+1)
1 2 3
| let arr = ['react', 'angular', 'vue']
console.log(~arr.indexOf('react'))
|
在 ES7 中使用 includes 代码如下:
1 2 3 4
| let arr = ['react', 'angular', 'vue']
console.log(arr.includes('react'))
|
还能在字符串中使用 includes:
1 2 3 4 5 6 7 8
| let str ='React Quickly'
if(str.toLowerCase().includes('react')){ console.log('Found "react"') }
|
includes 也可以在 NAN(非数字) 使用。
最后 includes 第二可选参数 fromIndex,这对于优化 是有好处的 ,因为 它允许从特定位置开始寻找匹配。
1 2 3 4 5 6 7 8
| console.log([1, 2, 3].includes(2)) console.log([1, 2, 3].includes(4)) console.log([1, 2, NaN].includes(NaN)) console.log([1, 2, -0].includes(+0)) console.log([1, 2, +0].includes(-0)) console.log(['a', 'b', 'c'].includes('a')) console.log(['a', 'b', 'c'].includes('a', 1))
|
includes
在一个数组或者列表中检查是否存在一个值。
Exponentiation Operator(求幂运算)
求幂运算大多数是做些数学计算,对于 3D,VR ,SVG 还有数据可视化非常有用。
在 ES6/2015ES,你能使用 Math.pow 创建一个短的递归箭头函数:
1 2 3 4 5
| calculateExponent = (base, exponent) => base * (--exponent > 1 ? calculateExponent(base, exponent) : base) console.log(calculateExponent(7, 12) === Math.pow(7, 12)) console.log(calculateExponent(2, 7) === Math.pow(2, 7))
|
在 ES7/ES2016 ,以数学向导 的开发者 可以使用更短的语法
1 2 3
| let a = 7 ** 12 console.log(a == Math.pow(7, 12))
|
还可以这样子
1 2 3 4 5 6 7
| let a = 7 a **= 12 let b = 2 b **= 7 console.log(a === Math.pow(7, 12)) console.log(b === Math.pow(2, 7))
|
ES8 常用新特性
Object.values/Object.entries
Object.values 和 Object.entries 是在 ES2017 规格中,它与 Object.keys 类似,返回数组类型,其序号和 Object.key 序号对应。类似 Python 中的 dict.iteritems()
Object.values 和 Object.entries 和 Object.keys 各自项返回是数组,相对应包括 key,value 或者可美剧对象 property/attribute
在 ES8/ES2017 之前,JavaScript 开发者迭代一个对象的自身属性时候不得不使用 Object.keys,通过迭代且使用 obj[key]获取 value 返回一个数组,很挫的:
1 2 3 4 5 6 7 8 9 10
| let obj = { a: 1, b: 2, c: 3 } Object.keys(obj).forEach((key,index)=>{ console.log(key,obj[key]);
})
|
而使用ES6/ES2015 中for/of稍微好点:
1 2 3 4 5
| let obj = { a: 1, b: 2, c: 3 } for(let key of Object.keys(obj)){ console.log(key,obj[key]); }
|
Object.values 返回对象自身可以迭代属性值(values)为数组类型。我们最好Array.prototype.forEach迭代它,结合ES6的箭头函数隐形返回值:
1 2
| let obj = { a: 1, b: 2, c: 3 } Object.values(obj).forEach((value) => console.log(value))
|
使用for/of
1 2 3 4 5 6 7
| let obj = {a: 1, b: 2, c: 3} for (let value of Object.values(obj)) { console.log(value) }
|
Object.entries
,在另一方面,将会返回对象自身可迭代属性key-value对数组(作为一个数组),他们(key-value)分别以数组存放数组中:
1 2 3 4 5
| let obj = {a: 1, b: 2, c: 3} console.log(JSON.stringify(Object.entries(obj)));
|
可以使用ES6/ES2015解构,从这嵌套数组中分别声明key和value
1 2 3 4 5 6 7 8 9 10
| let obj = { a: 1, b: 2, c: 3 } Object.entries(obj).forEach(([key, value]) => { console.log(`${key} is ${value}`) })
|
同样使用ES6 for/of(毕竟全部都是数组)遍历Object.entries返回来的结果值:
1 2 3 4 5 6 7
| let obj = {a: 1, b: 2, c: 3} for (let [key, value] of Object.entries(obj)) { console.log(`${key} is ${value}`) }
|
String padding(字符串填充)
String.prototype.padStart 和 String.prototype.padEnd在javascript字符操作是一个不错的体验,帮助避免依赖而外的库。
padStart()在开始部位填充,返回一个给出长度的字符串,填充物给定字符串,把字符串填充到期望的长度。从字符串的左边开始(至少大部分西方语言),一个经典例子是使用空格创建列:
1 2 3 4 5 6 7 8 9 10 11 12
| console.log('react'.padStart(10)) console.log('backbone'.padStart(10)) console.log('0.00'.padStart(20)) console.log('10,000.00'.padStart(20)) console.log('250,000.00'.padStart(20))
|
第二个参数,让我们放一些其他的填充字符替代空字符串,一个字符串填充
1 2 3 4 5
| console.log('react'.padStart(10,'#')) console.log('backbone'.padStart(10,'#'))
|
Object.getOwnPropertyDescriptors
函数参数列表和调用中的尾逗号(Trailing commas)
异步函数(Async Functions)