ES6 解构赋值

  解构赋值,就是怎么快速地从对象和数组中获取到你想要的数据,先来看对象的解构赋值。web

let person = { name: 'sam', age: '28' }; let {name, age} = person; // 解构赋值
console.log(name, age) // 'sam' 28

  对象字面量的方式声明了两个变量name 和age, let {name, age} 放到了等号的左边, 右边就是咱们要想从中获取数据的对象。赋值的依据就是对象的属性,变量名和对象的属性名一致。对象的解构赋值就是对对象进行分解,从对象中找出和声明的变量名一致的属性名,而后把属性值赋值给对应的变量。这时,也会出现一个问题,当声明的变量名,在对象中没有对应的属性名呢?很简单,这个变量取值undefined. 数组

let {job } = person; console.log(job) // undefined

  但变量取值undefined, 对之后的计算或操做不太友好,最好给它一个默认值。默认值的赋值方式,也很简单,使用= 进行赋值。函数

let {job = 'web' } = person; console.log(job) // web

  以上这种解构赋值的方式,还有一个限制,就是声明的变量名必须和对象的属性名一致。若是咱们已经声明了一个和对象同名变量,那就不能再声明这个相同的变量了, 那是否是就不能使用解构赋值了?也不是,就是语法稍微复杂了一点url

let {name: localName } = person; console.log(localName) // sam

  语法为{对象的属性名: 声明变量名}, 意思是获取到对象中name 属性对应的值,而后把它赋值给 localName变量,因此,在这种状况下,就不能访问name了,不然会报错。固然在这种赋值方式下,也能够提供默认值,由于咱们始终是从对象中获取属性值,很容易取到对象中没有的属性spa

let {job: localJob = 'web' } = person; console.log(localJob) // web

  取person 对象中的job 属性的值,赋值给localJob 变量,很明显,赋值的是undefined, 由于person 中没有job 属性,localJob 变量也就取值undefined, 有必要给它提供一个默认值。rest

  以上都是声明变量,使用解构赋值,其实单纯的赋值也能够是使用解构赋值。变量以前就已经声明了,咱们只想给已声明的变量赋值,那就直接把变量放到大括号里面,放到等号的左边,右边放要解构的对象code

let person = { name: 'sam', age: '28' }; let age = 10; ({age} = person) // 只是赋值,注意要把解构表达式放到小括号里面

  要注意一点,使用解构的方式,只进行赋值操做时,要把整个表达式用小括号括起来。若是不用括号括起来,{age} = person,  第一个{ 会被js 解析为块级做用域的开始,你不能给一个做用域赋值,因此就会报错。像{age} = person 这样的解构赋值表达式,赋值完以后,整个表达式的值仍然是=后面的对象,提及来可能有点不太理解,举个例子就简单了对象

let age = 10; let obj; obj = {age} = person; console.log(age, obj) // 28 { name: 'sam', age: '28' }

  看一下obj ={age} = person;  赋值操做都是从右边开始计算, 先{age}= person,  person 对象进行解构赋值,而后再赋值给obj. 正如刚才所说,解构赋值表达式最终的结果是=后边的对象, {age} = person 解构赋值完成之后获得的值是person 对象,而后把person 对象赋值给了obj, 如今obj === person 为true. 若是这样的话,person的解构赋值也就能够 这样写blog

({age} = {name} = person);

  嵌套对象也能够进行解构,只不过语法看起来有点别扭。索引

let person = { address: { province: '广东', city: '深圳' } } let {address: {province}} = person; console.log(province)

  person 对象嵌套了address 对象,那怎么找到address 对象中的属性呢?确定是先找address 属性,只有找到它,才能找到它下面的属性。address 属性的解构就和普通解构没有什么区别,let {address} = person.  如今就是向下一步,解析address. 解析address, 无非就是把address 赋值给另一个解构对象, let {province} = address. address 怎么赋值给别的对象呢? 在解构中使用的是冒号  let {address: anotherAddress} = person.  咱们把anotherAddress 换成{province} 又能够了。 let {address: {province}} = person, 没有问题了。嵌套解构,至关于找到了一个address 属性, 把它赋值给一个匿名的变量(:右侧是要赋值给的目标),正好,这个匿名的变量是一个对象,又能够按照解构的方式取对象里面的属性值{province} 就产生了。

   对象的解构赋值差很少,再说一下数组的解构赋值。数组是使用数组字面量的方式来解构赋值,也就是说,声明变量的时候,把变量放在数组字面量中。

let colors = ['red', 'green']; let [firstColor, secondColor] = colors; console.log(firstColor, secondColor); // 'red' 'green'

  那数组是怎么实现解构赋值的? 用的是位置或索引,由于数组中,元素的排列都是有顺序的,第一个元素就是在数组的第一个位置上,因此声明变量的时候,第一个变量就对应数组中的第一个位置的元素,第二个变量对应数组中第二位置的元素, firstColor 就对应数组中的第一个值 'red', secondColor 就对应数组中的第二个值'green'.  那若是只想获取第二个值呢? 第一个变量就不用声明了,直接写一个逗号,

let colors = ['red', 'green']; let [, secondColor] = colors; console.log( secondColor); // green'

  一个逗号表明的就是一个位置。数组的解构赋值就是位置的一一对应,咱们想要数组中哪一个元素的值,声明的变量就要放到哪一个位置上,若是这个位置是中间位置,而前面的元素你有不想要,那就用逗号隔开,好比你想要第六位置的元素的值,前面就是5个逗号。

let colors = ['red', 'green']; let [,,,,, sixColor] = colors;

  固然对于这个例子来讲,没有太大的意义,由于colors 数组只有两个元素, 第六位置上确定没有值。 sixColor 若是没有获取到值,确定是undefined, 这时也能够给它一个默认值。

let [,,,,, sixColor = 'black'] = colors;

  和对象的解构赋值同样,除了声明时的解构赋值外,直接给变量赋值也是没问题的 。

let colors = [ "red", "green", "blue" ]; let firstColor = "black"; let secondColor = "purple"; [ firstColor, secondColor ] = colors; console.log(firstColor, secondColor); // "red" "green"

  这种解构赋值的方式有一个巨大的做用,咱们能够很轻松的交换两个变量的值。

let x = 1, y = 2; [y, x] = [x, y]; console.log(x, y); // 2 1

  再来简单的看一下嵌套数组的解构赋值,一个例子就很明显了。

let colors = [ "red", [ "green", "lightgreen" ], "blue" ]; let [ firstColor, [ secondColor ] ] = colors; console.log(firstColor, secondColor); // "red" "green"

  数组解构赋值的时候,能够看作把colors 的第二项赋值给一个匿名变量,这个变量正好也是一个数组,顺便就再进行一次解构赋值。能够看到嵌套数组的解构赋值,就至关于比着葫芦画瓢, 要解构的数组长什么样,声明变量的时候所用到的数组格式就长什么样,只不过它里面放到都是变量,变量和数组元素的一一对应。

  除了和对象的解构赋值相同点以外,数组解构还可使用... 操做符, 用法和函数的参数使用方法同样,把剩余的元素收集起来。

let colors = [ "red", "green", "lightgreen" , "blue" ]; let [ firstColor, ...restColor ] = colors; console.log(firstColor); // "red" 
console.log(restColor); // [ 'green', 'lightgreen', 'blue' ]

  解构赋值的另一个做用是函数参数的定义,解构赋值的核心就是赋值,只要是赋值的地方,咱们均可以用解构赋值表达式。函数的参数正好也是赋值,函数调用的时候就是把实参的值赋值给形参,那么形参的定义,就可使用解构赋值的声明变量的方式,原来,咱们的形参直接定义一个options , 如今就能够定义成options 要接受的内容。{method, time}

function getRequest(url, {method,time}) { }

  这样函数的使用就会更加的方便,一看函数声明就知道传递什么参数,还可给它赋值一个默认的参数,这样函数的运行就更加不会出错。

function getRequest(url, {method = "get",time = "2000"} = {}) { }

   解构和重构,这是you don't kown js 中的提到的一个相对高级的用法, 有一个默认的default 配置,就是一个default 的变量。

const defaults = { options: { remove: true, enable: false, instance: {} }, log: { warn: true, error: true } }

  如今有一个配置,就是一个config 变量,它也必须有和default 同样的格式和属性,若是config配置中的属性有值,就使用config 中的值,若是config 属性中没有值,就要使用default 中的值进行赋默认值,假设如今config 变量以下:

let config = { options: { remove: false, instance: null } };

  那怎么才能把default 中的值放合并到config 中? 它的作法以下,先对config 进行解构,而后再重建config, 代码以下

// 最外面的括号声明的是一个块级做用域
{ let { // 解构赋值
 options: { remove = defaults.options.remove, enable = defaults.options.enable, instance = defaults.options.enable } = {}, log: { warn = defaults.log.warn, error = defaults.log.error } = {} } = config; // restructure 重建
  config = { options: { remove, enable, instance }, log: { warn, error } }; }

  稍微解释一下,先对config 进行解构, let {options: {} = {},  log: {} ={}} = config,  把config中的options 和log 解构出来,为了防止config中没有options和 log,它用空对象进行了默认值的赋值操做,注意,这个语法不对, 只是为了解释。而后再对options 和log 又进行了一个解构,options: {remove = defaults.options.remove}, options 中的remove 取出值,若是没有值,就使用默认值defaults中的值。这时就是声明了一个remove 变量,它的值先是config 中的remove 属性值,若是config 中没有remove属性,它就使用defaults 中的remove值。其它的enable, instance,  warn, error 也是一样的道理,它们就是变量。有了变量后,从新组装了config

相关文章
相关标签/搜索