js -- ES6(三)-- 变量的解构赋值(根据阮一峰ES6标准入门整理 更新中。。。)
2018-01-12 15:28
756 查看
6>目前正在学习ES6,学到哪更新到哪里,都是基本的知识,复杂的目前还不会,涉及的代码都是亲自运行过的,若发现错误请指正。
① 解构成功
② 解构不成功,变量的值就等于undefined
③ 不完全解构 ,等号左边的模式只匹配等号右边数组的一部分
④ 解构失败,等号的右边是不可遍历的结构,会报错
ES6使用严格相等运算符(===)判断一个位置是否有值,所以,如果一个数组成员不严格等于undefined,默认值是不会生效的
如果默认值是一个表达式,那么这个表达式是惰性求值的,只有在用到的时候才会求值
例如下面的例子,因为x能取到值,所以函数 f 根本不会执行
等价于:
默认值可以引用解构赋值的其他变量,但该变量必须已经声明
① 变量与属性同名
② 变量名与属性名不一致
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
③ 重复声明
对于 let 和const 而言,变量不能重新声明,所以一旦赋值的变量以前声明过,就会报错
如果没有第二个 let 命令,就不会报错
④ 嵌套赋值,模式不会被复制
这里只有 line 是变量,loc 和 start 都是模式,不会被赋值
⑤ 对象解构指定默认值,默认值生效的条件是对象的属性值严格等于undefined。
⑥ 解构赋值已经声明的变量
报错原因是,js引擎会将{x}理解成一个代码块,从而发生语法错误。
正确的写法:不将大括号写在行首,避免js将其解释为代码块
类似数组的对象都有length属性,因此还可以对这个属性解构赋值。
② undefined 和 null 无法转为对象,解构赋值会报错
① 变量声明语句中,模式不能带有圆括号
② 函数参数中,模式不能带有圆括号,函数参数也属于变量声明
③ 不能将整个模式或嵌套模式中的一层放在圆括号中。
可以使用圆括号的情况
① 赋值语句的非模式部分可以使用圆括号
(2)从函数返回多个数值
函数只能返回一个值,如果要返回多个值,只能将其放在数组或对象中返回
(3)函数参数的定义
(4)提取JSON数据
(5)函数参数的默认值
(6)遍历 Map 结构
部署了Iterator 接口的对象,都可以用 for … of 循环遍历。
·
[b]补充:
Iterator
遍历器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作。
作用:
为各种数据结构,提供一个统一的、简便的访问接口
使得数据结构的成员能够按某种次序排列
ES6创造了一种新的遍历命令 for … of 循环,Iterator 接口主要供 for … of 使用
ES6中有三类数据结构原生具备Iterator接口:数组、某些类似数组的对象、Set 和 Map 结构
三、变量的解构赋值
1、数组的解构赋值
解构:按照一定模式,从数组和对象中提取值,对变量进行赋值基本用法
从数组中提取值,按照位置的对应关系对变量赋值,只要等号两边的模式相同,左边的变量就会被赋予对应的值① 解构成功
let [A,,[],...Z]=[1,2,[[3],4],5,6]; console.log(A);//1 console.log(B);//3 console.log(Z);//[5,6]
② 解构不成功,变量的值就等于undefined
let [x,y,...z]=['a']; console.log(x);//'a' console.log(y);//undefined console.log(z);//[]
③ 不完全解构 ,等号左边的模式只匹配等号右边数组的一部分
let [a,[b],d]=[1,[2,3],4]; console.log(a);//1 console.log(b);//2 console.log(d);//4
④ 解构失败,等号的右边是不可遍历的结构,会报错
let [foo] =1; //undefined is not a function let [foo] =false; //undefined is not a function let [foo] =NaN; //undefined is not a function let [foo] =undefined; //Cannot read property 'Symbol(Symbol.iterator)' of undefined let [foo] =null; //Cannot read property 'Symbol(Symbol.iterator)' of null let [foo] ={}; //undefined is not a function
默认值
解构赋值允许指定默认值[x,y='b']=['a']; console.log(x);//'a' console.log(y);//'b'
ES6使用严格相等运算符(===)判断一个位置是否有值,所以,如果一个数组成员不严格等于undefined,默认值是不会生效的
var [x=1]=[undefined]; console.log(x);//1,严格等于undefined,默认值生效 var [x=1]=[null]; console.log(x);//null,不严格等于undefined,默认值不生效
如果默认值是一个表达式,那么这个表达式是惰性求值的,只有在用到的时候才会求值
例如下面的例子,因为x能取到值,所以函数 f 根本不会执行
function f(){ console.log('aaa'); } const a = [1]; let [x=f()] = a; console.log(x);//1
等价于:
function f(){ console.log('aaa'); } const a = [1]; let x; if(a[0]==undefined){ x=f(); }else{ x=a[0]; } console.log(x);//1
默认值可以引用解构赋值的其他变量,但该变量必须已经声明
let [x=1,y=x] = [];//1,1 let [x=1,y=x] = [2];//2,2 let [x=1,y=x] = [1,2];//1,2 let [x=y,y=1] = [];//y is not defined, x 用到默认值 y 时,y 还没有声明
2、对象的解构赋值
对象的解构与数组有一个重要的不同,数组的元素是按照次序排列的,变量的取值由它的位置决定。对象的属性没有次序,变量只要与属性同名,就能取到正确的值。① 变量与属性同名
var {bar,foo} = {foo:'aaa',bar:'bbb'}; console.log(foo);//'aaa' console.log(bar);//'bbb' var {hh} = {foo:'aaa',bar:'bbb'}; console.log(hh);//undefined,变量没有对应的同名属性,导致取不到值,等于undefined
② 变量名与属性名不一致
var {foo:hh} = {foo:'aaa',bar:'bbb'}; console.log(hh);//'aaa'
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
③ 重复声明
对于 let 和const 而言,变量不能重新声明,所以一旦赋值的变量以前声明过,就会报错
let hh; let {foo:hh} = {foo:1}; console.log(hh);//Identifier 'hh' has already been declared标识符“hh”已经声明
如果没有第二个 let 命令,就不会报错
let hh; ({foo:hh} = {foo:1}); console.log(hh);//1
④ 嵌套赋值,模式不会被复制
var {loc:{start:{line}}} = node; console.log(loc);//log is not defined console.log(start);//start is not defined console.log(line);
这里只有 line 是变量,loc 和 start 都是模式,不会被赋值
⑤ 对象解构指定默认值,默认值生效的条件是对象的属性值严格等于undefined。
var {x=3} = {x:undefined}; console.log(x);//3 var {x=3} = {x:null}; console.log(x);//null var {foo} = {bar:'fff'}; console.log(foo);//undefined var {foo:{bar}} = {fff:'fff'}//Cannot match against 'undefined' or 'null'.
⑥ 解构赋值已经声明的变量
var x; {x}={x:1} console.log(x);//Unexpected token =
报错原因是,js引擎会将{x}理解成一个代码块,从而发生语法错误。
正确的写法:不将大括号写在行首,避免js将其解释为代码块
var x; ({x}={x:1}); console.log(x);//1
3、字符串的解构赋值
字符串解构赋值时,字符串被转换成了一个类似数组的对象。const [a,b,c,,d] = 'hello'; console.log(a);//a console.log(d);//o
类似数组的对象都有length属性,因此还可以对这个属性解构赋值。
let {length} = 'hello'; console.log(length);
4、数值和布尔值的解构赋值
① 等号右边是数值或布尔值,先转化为对象再赋值let {toString:s}=123; console.log(s===Number.prototype.toString)//true let {toString:s}=true; console.log(s===Boolean.prototype.toString);//true ps:不是很懂什么意思
② undefined 和 null 无法转为对象,解构赋值会报错
let {prop:x} = undefined; //Cannot match against 'undefined' or 'null'. let {prop:y} = null; //Cannot match against 'undefined' or 'null'.
5、函数参数的解构赋值
function move({x=0,y=0}={}){ return [x,y]; } console.log(move({x: 3, y: 8}));//[3,8] console.log(move({x: 3}));//[3,0] console.log(move({}));//[0,0] console.log(move());//[0,0] 函数 move 的参数是一个对象,通过对这个对象进行解构,得到变量 x 和 y 的值。如果解构失败,则 x 和 y 等于默认值。
function move({x,y}={x:0,y:0}){ return [x,y]; } console.log(move({x: 3, y: 8}));//[3,8] console.log(move({x: 3}));//[3,undefined] console.log(move({}));//[undefined,undefined] console.log(move());//[0,0] 函数 move 的参数指定默认值,而不是为变量 x 和 y 指定默认值
6、圆括号问题
不能使用圆括号的情况① 变量声明语句中,模式不能带有圆括号
// Unexpected token ( var [(a)] = [1]; var {x:(c)} = {}; var {o:({p:p})} = {o:{p:2}};
② 函数参数中,模式不能带有圆括号,函数参数也属于变量声明
// Unexpected token ( function f([(z)]) { return z; } console.log(f(2));
③ 不能将整个模式或嵌套模式中的一层放在圆括号中。
// Unexpected token ( //整个模式 ({p:a}) = {p:42}; ([a]) = [5]; //嵌套模式 [({p:a}),{x,c}] = [{},{}];
可以使用圆括号的情况
① 赋值语句的非模式部分可以使用圆括号
[(b)] = [3]; console.log(b);//3 ({p:(d)} = {}); console.log(d);//undefined [(parseInt.prop)] = [3]; console.log(parseInt.prop);//3
7、解构赋值的用途
(1)交换变量的值[x,y] = [x,y];
(2)从函数返回多个数值
函数只能返回一个值,如果要返回多个值,只能将其放在数组或对象中返回
//返回一个数组 function example() { return [1,2,3]; } var [a,b,c] = example(); console.log([a, b, c]);//[1,2,3]
//返回一个对象 function example() { return { foo:1, bar:2 }; } var {foo,bar} = example(); console.log({foo,bar});//{foo:1,bar:2}
(3)函数参数的定义
(4)提取JSON数据
(5)函数参数的默认值
(6)遍历 Map 结构
部署了Iterator 接口的对象,都可以用 for … of 循环遍历。
·
[b]补充:
Iterator
遍历器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作。
作用:
为各种数据结构,提供一个统一的、简便的访问接口
使得数据结构的成员能够按某种次序排列
ES6创造了一种新的遍历命令 for … of 循环,Iterator 接口主要供 for … of 使用
ES6中有三类数据结构原生具备Iterator接口:数组、某些类似数组的对象、Set 和 Map 结构
相关文章推荐
- js -- ES6(一)-- 简介(根据阮一峰ES6标准入门整理)
- js -- ES6(二)-- let 和 const 命令(根据阮一峰ES6标准入门整理)
- js-es6-变量的解构赋值
- es6 变量的解构赋值
- ES6小实验-变量的解构赋值
- ES6学习——变量的解构赋值
- ES6-变量的解构赋值
- 【es6】【变量的解构赋值】【数组解构赋值】
- js 交换赋值我认为最简单的方法 (ES6解构)
- 【ES6】变量的解构赋值
- 《ES6标准入门》:变量的解构赋值
- es6-变量解构赋值
- 【es6】【变量的解构赋值】【对象解构赋值】
- ES6:变量的解构赋值
- ES6中变量的解构与赋值
- ES6学习之变量的解构赋值
- es6 变量的解构赋值
- es6-变量的解构赋值
- ES6-变量解构赋值
- ES6入门——变量的解构赋值