变量的解构赋值
数组的解构赋值
es6 允许按照一定的模式从数组和对象中提取值,然后再赋值(这被称为解构) 可以这样写
例子
let [a,b,c] = [1,2,3]
let [,,third] = [1,2,3] //third = 3
let [x,,y,,z] = [1,2,3,4,5] //x=1 y=3 z=5
let [x,y,z] = [,0,3] // x= undefined y=0 z=3
复制代码
如果解构不成功,变量的值就等于undefined。赋值的等号右边有值就可以赋值成功 如果等号右边不是数组(或者严格来说是不可遍历的解构)就会报错。 等号右边的值或转为对象以后不具备Iterator接口 *对于Set结构也可以使用数组的解构赋值
例子
let [x,y,z] = new Set([1,2,3])
复制代码
只要某种数据解构具有Iterator接口,都可以采用数组形式的解构赋值 赋值时我们可以给定一个默认值
例子
let [x,y=1] = [0] // x=0 y=1
let [x,y=1] = [0,2] //x=0 y=2
复制代码
代码中赋值使用其它变量,该变量要是声明过的如果不是声明过的就会报错(会按照顺序来执行)
例子
let [x = 1, y = x] = []; I I x=l ; y=l let [x = 1, y = x] = [2]; II x=2 ; y=2 let [ x = 1, y = x] = [ 1, 2] ; II x=l; y=2 let [ x = y, y = l] = [ ] ; II ReferenceError
## 对象的解构赋值
对象的解构与数组的解构有一个重要的不同。数组的元素是按次序排列的,变量的取值是由它的位置决定的:
对象的属性没有次序,变量必须与属性同名才能渠道正确的值。
### 例子
```javaScript
let obj = {first:'hello',second:'world'}
let {first: foo,second:doo} = obj // foo=hello doo=world
复制代码
在上面代码中first和second是匹配模式,foo doo这两个才是变量,我们赋值的时候是通过前面的匹配模式找 到变量给变量去赋值. 当我们将一个已经声明的变量用于解构赋值我们需要注意的是要用一个()把其括起来(因为{X}会被理解成为一 个代码块,我们需要避免这样)
例子
错误写法
let x
{x} = {x:1}// SyntaxError: syntax error 会发生语法错误
复制代码
正确写法
let x
({x} = {x:1})
复制代码
由于数组的本质是特殊的对象,因此可以对数组进行数组对象属性的解构、
例子
let arr = [1,2,3]
let {0:first,[arr.length -1]:last} = arr
// first = 1 last =3
复制代码
字符串的解构赋值
字符串在解构赋值的时候被转换成为了一个类似于数组的对象,类似数组对象都会有一个length属性,我们也可以对 这个属性进行解构赋值。
例子
const [a,b,c,d,e] = 'hello'
// a= 'h' b= 'e' c= 'l' d= 'l' e= 'o'
let{length:len} = 'hello'
// len = 5
复制代码
数值和布尔值的解构赋值
在解构时如果等号右边的是数值和布尔类型,会先转换为对象
例子(这个例子给的之后敲了一下发现 s是一个function)
let {toString : s} = 123 ;
s === Number . prototype.toString // true s = ƒ toString() { [native code] }
let {toString: s} = true;
s === Boolean.prototype.toString // true s = ƒ toString() { [native code] }
复制代码
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象, 所以对它们进行解构赋值时都会报错。
let { prop: x ) =undefined; // TypeError
let { prop: y ) = null; I I TypeError
复制代码
函数的解构赋值
函数的参数也可以使用解构赋值
例子
function add([x,y]){
return x + y
}
add([1,2]) // 3
复制代码
上面的add的参数在传入参数的那一刻,数组参数就被解构成变量x和y。对于函数内部的代码来说,它们能感受到 的参数就是x和y。
例子
[[1,2],[3,4]].map(([a,b]) => a+b) //[3, 7]
复制代码
函数参数的解构我们也可以使用默认值
例子
function testDemo({x=0,y=0} ={}){
return [x,y]
}
testDemo({x:3,y:8}) // [3,8]
testDemo({x:3}) //[3,0]
复制代码
上面的代码就是如果解构失败了不会等于undefined会等于默认值 0
例子
function move({x,y} = {x:0,y:0}){
return [x,y]
}
move({x:3,y:8}) // [3,8]
move({x:3}) //[3,undefined]
move({}) //[undefined,undefined]
move() //[0,0]
复制代码
上面的代码就是没有给定默认值只是给了一个默认的传参,如果没有默认传参就是输出默认的传参的值,如果 传了参数就不使用默认的参数。
圆括号问题
解构赋值赋值很方便但是解析起来很麻烦。对于编译器来说它不可能从一开始就能解析到 等号的时候才能知道 式子是模式还是表达式。(ES6的规则是,只要有可能导致解构的歧义,就不得使用圆括号)
- 不能使用圆括号的情况 1.变量声明语句 2.函数参数 3.赋值语句的模式
- 可以使用圆括号的情况 可以使用圆括号的情况只有一种赋值语句的非模式部分可以使用圆括号。
用途
- 交换变量的值
- 从函数返回多个值
- 函数参数的定义
- 提取JSON数据
- 函数参数的默认值
- 遍历Map解构
- 输入模块的制定方法