您的位置:首页 > 其它

ES6学习笔记-变量解构赋值

2017-02-12 11:25 274 查看
ES6允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。

数组的解构赋值

ES6支持如下赋值方式,例如:

let [a, b, c] = [1, 2, 3];//a=1, b=2, c=3
上面代码表示,可以从数组中提取值,并按照相应位置,对变量进行赋值。本质上,这种方式属于”模式匹配”,只要左右两边模式相同,左边的变量就会被赋予相应的值;

如果等号右边的数组只能匹配部分等号左边的数组,那么左边多余部分变量解构就会失败,默认值为undefined;

如果等号左边的数组只能匹配部分等号右边的数组,那么解构依然会成功,称之为不完全解构;

如果等号右边的不是可遍历结构( Iterator 接口),那么将会报错(因此,Set属于可遍历结构,也可用于数组的解构赋值);

解构赋值允许指定默认值;如果使用的默认值是一个表达式,那么他是惰性的,只有被使用到时,才会计算;默认值生效的条件是等号右边对应位置,必须是undefined(null并不行);同时默认值也可引用 其他解构赋值变量,但前提是必须先声明;

对象的解构赋值

对象的属性解构与对数组解构不同;数组解构是根据数组元素顺序进行赋值,而对象属性没有顺序,要求变量名必须与属性名相同,才能正确取到值;例如:

let { bar, foo } = { foo: "aaa", bar: "bbb" };//bar='bbb', foo='aaa'


如果变量名和属性不一致,那么必须写成如下方式:

var { foo: baz } = { foo: 'aaa', bar: 'bbb' };//baz= "aaa", foo // error: foo is not defined


实际说明了对象的解构赋值是以下形式的简写:

let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };


也就是说,对象的解构赋值的内部机制,是先找到同名属性,再赋给对应的变量,真正被复制的是后者,而不是前者。

PS:采用这种写法时,变量的声明和赋值是一体的。对于let和const来说,变量不能重新声明,所以一旦赋值的变量以前声明过,就会报错。

对象解构赋值也可指定默认值;解构失败,没有默认值的变量值等于undefined;

用于嵌套对象的解构,例:

var node = {

** loc: {

****start: {

******line: 1,

******column: 5

****}

** }

};

var { loc: { start: { line }} } = node;

line // 1

loc  // error: loc is undefined

start // error: start is undefined


上面代码中,只有line是变量,loc和start都是模式,不会被赋值;

如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错,例:
let {foo: {bar}} = {baz: 'baz'};// 报错


原因很简单,因为foo这时等于undefined,再取子属性就会报错;

如果要将一个已经定义的变量用于对象的解构赋值,必须非常小心,因为JavaScript引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首(外层加上个小括号),避免JavaScript将其解释为代码块,才能解决这个问题。例:
let x;

{x} = {x: 1};// 错误的写

({x} = {x: 1});// 正确的写法


由于数组是特殊对象,因此可以对数组进行对象属性的解构,数组下标即为对象属性。例:

let arr = [1, 2, 3];

let {0 : first, [arr.length - 1] : last} = arr;//first=1,last=3


字符串解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象;例:
const [a, b, c, d, e] = 'hello';

//a ="h", b = "e", c = "l", d = "l",e = "o"


类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值;例:

let {length : len} = 'hello';//len = 5


函数参数也可解构赋值

PS:解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: