ES6 新特性梳理系列文章将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!
JavaScript 与 ECMAScript
JavaScript 诞生于1995年,设计者是就职于 Netscape 公司的工程师 Brendan Eich。它是一门仅用10天就完成设计的编程语言,但至今为止已对业界保持26年的影响,且势头愈发强劲
1996年 Netscape 将 JavaScript 提交给ECMA,希望它可以成为“标准化一个通用的、跨平台的、中立于厂商的脚本语言的语法和语义标准”,1997年 ECMA 确定将 JavaScript 作为浏览器脚本语言的标准,并为之重命名为 ECMAScript,所以通常来讲我们将 ECMAScript 视为 JavaScript 的标准,而 JavaScript 则是 ECMAScript 的实现及扩展
1997年-1999年连续发布了ES1-ES3发布,2000年开始酝酿新版本的升级内容,中间因标准委员会意见未能达成一致,只做了部分功能的小范围升级及支持,于2009年12月发布了过渡版 ECMAScript 5.0,2011年6月发布 ECMAScript 5.1 并成为 ISO 国际标准
2013年3月 ECMAScript 6 草案冻结,2013年12月 ECMAScript 草案发布,2015年6月 ECMAScript 6 正式通过,成为新的国际标准。ES6 泛指自2015年升级为 ECMAScript 6.0 后的所有子版本,如:ES2015-ES2020,等同于ES6.0-ES6.5,这是 JavaScript 走向企业级编程语言的强势升级
不断升级的标准与实现,对于开发效率及产品质量起到强有力的支撑,接下来我们开始梳理ES6的新特性吧!
何为变量的解构赋值
变量的解构赋值是 ES6 提出的一种变量赋值方式,可以按照一定的模式从数组或者对象中取值,然后将取到的值赋值给变量。一定的模式,其实就是一一对应的关系,比如:
var [a,b,c] = [1,2,3]
a // 1
b // 2
c // 3
var [ , ,a] = [1,2,3]
a // 3
var [a,b] = [1,2,3]
a //1
b //2
var [a,...b] = [1,2,3]
a // 1
b // [2,3]
vat [a,b,c] = [1,2]
a // 1
b // 2
c // undefined
什么情况下不可解构赋值
其实,本质上来说,只要某种数据结构具有 Iterator 接口(是可遍历的结构),都可以采用数组形式的解构赋值。比如如下情况就会解构失败,导致报错:
let [a] = 1;
let [a] = false;
let [a] = NaN;
let [a] = undefined;
let [a] = null;
let [a] = {};
解构赋值还可以指定默认值
当对数组进行解构赋值时,按照模式匹配方式,并没有找到匹配到的值,那么就可以使用开始指定的默认值。当然,使用你所指定的默认值,也有一个前提,那就是你这个变量(有指定默认值)所匹配到的值(根据解构赋值进行的模式匹配)为 undefined 时,你才可以拿到你开始指定的默认值。否则,开始指定的默认值将不会生效。
指定的方式也很简单:
var [a = true] = []
a // true
var [a,b = 'c'] = [1]
a // 1
b // c 默认值
var [a,b = 'c'] = [1,undefined]
a // 1
b // c 默认值
var [a,b = 'c'] = [1,null]
a // 1
b // null 因为 null 不是 undefined
当然,指定的默认值也可以是一个变量,但前提是这个变量必须已经声明了
let [a = 1,b = a] = []
a // 1
b // 1
let [a = 1,b = a] = [2]
a // 2 因为a匹配到了值‘2’,使用匹配到的值
b // 2 因为b使用的默认值a已经变成了2
let [a = 1,b = a] = [2,3]
a // 2 因为a匹配到了值‘2’,使用匹配到的值
b // 3 因为b匹配到了值‘3’,使用匹配到的值
let [a = b,b = 1] = []
// 报错 因为a没有匹配到值,使用的默认值b还没有声明
对象的解构赋值
在进行对象的解构赋值的时候,与数组并不一样。数组根据的是下标索引值的一一对应,对象根据的是属性名的一一对应。
var {a,b} = {a:1,b:2}
a // 1
b // 2
var {c} = {a:1,b:2}
c // undefined
var {a:c} = {a:1,b:2}
c // 1
var {b:d,a:c} = {a:1,b:2}
c // 1
d // 2
实际上,var {a,b} = {a:1,b:2} 是 var {a:a,b:b} = {a:1,b:2} 的简写形式,这里使用了 ES6 的对象写法的简化形式,即当变量名和属性名一致时,可以省略属性名。 比如:
var username='zhangSan';
var age=18;
// 以前的写法
// var obj={
// username:username,
// age:age
// };
//ES6简化后的的写法
let obj={
username,//同名的属性可以简略不写
age
}
也就是说,对象的解构赋值,本质上是根据属性名去查找,赋值是对后面的变量进行赋值。
var {a:b} = {a:1}
b // 1
a // error: a is not defined
当然,对象的解构赋值也可以指定默认值。根据指定的默认值的变量名和匹配对象的属性名进行匹配,如果没有匹配成功(对象的属性中不包含该变量),那么就会使用当前变量的默认值。和数组匹配一样,使用默认值的前提也是,匹配到的属性值为 undefined 时,才会使用指定的默认值
var {a = 1} = {}a // 1
var {a,b = 2} = {a:1}
a // 1 匹配到的1
b // 2 默认值2
var {a:b = 1} = {}
b // 1
a //error: a is not defined
var {a:b = 1} = {a:2}
b // 2
a // error: a is not defined
var {a = 1} = {a:undefined};
a // 1 因为匹配到的是undefined,所以使用默认值
var {a = 1} = {a:null};
a // null
当进行对象嵌套的时候,要小心,可能会导致报错哦!你要保证子对象的父属性存在,也就是父属性不是 undefined
var {a:{b}} = {c:2}
// 报错 因为a没有匹配到,a为undefined,再去子对象{b},就会报错
字符串的解构赋值
我们可以对字符串转换为一个类似数组的对象
var [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
var {length:len} = 'hello'
len // 5 因为字符串都有一个length属性
数值和布尔值的解构赋值
对数值和布尔值进行解构赋值的时候,会先把他们转换为对象,然后在对象的原型链上找相关属性。如果不能将值转换为对象,那么就会报错。比如:
var {toString:a} = 1
a // Number.prototype.toString 返回对Number的toString方法的引用
var {toString:a} = true
a // Boolean.prototype.toString 返回对Number的toString方法的引用
var {a} = undefined
// 报错
var {a} = null
// 报错
函数参数的解构赋值
我们可以对函数传入的参数进行解构赋值,比如:
function add([a,b]){
return a + b
}
add[1,2] // 3
函数参数也会有默认值形式,当匹配到的值为 undefined 时,将会使用指定的默认值。
function fn({a = 0, b = 0} = {}) {
return [a, b];
}
fn({a: 1, b: 8}); // [3, 8]
fn({a: 3}); // [3, 0]
fn({}); // [0, 0]
fn(); // [0, 0]
ES6 新特性梳理系列文章将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!
叶阳辉
HFun 前端攻城狮