通俗易懂理解ES6 - 变量的解构赋值

栏目: JavaScript · 发布时间: 5年前

内容简介:万丈高楼平地起,欲练此功,必先打好基本功: )编程语言总少不了变量赋值;ES6中引入了新的赋值形式:什么是迭代器(Iterator)?这有两篇文章可以参考一下(对阅读下文会有帮助):

万丈高楼平地起,欲练此功,必先打好基本功: )

编程语言总少不了变量赋值;ES6中引入了新的赋值形式: 解构赋值 ;解构赋值大大的简化了变量赋值的代码,解构赋值仅能对具有迭代器(Iterator)的数据使用;

什么是迭代器(Iterator)?这有两篇文章可以参考一下(对阅读下文会有帮助):

我本人对iterator的总结理解

阮一峰老师写的极客学院文章

赋值和解构赋值

解构赋值,直白地理解就是 解析解构进行赋值 ~

在ES5中,我们对变量的赋值是这样的

var a = {item: 'obj',item1: 'obj1'},
    b = ['c1','c2','c3'],
    c = 'test',
    d = 'test2'
var item = b.item,
    item1 = b.item1,
    item2 = b.item2,
    arrItem = c[0],
    arrItem1 = c[1];
item;       //obj
item1;      //obj1
item2;      //undefined
arrItem;    //c1
arrItem1;   //c2
复制代码

emmmmm...好麻烦~

再看看使用ES6解构赋值的写法:

let a = {item: 'obj',item1: 'obj1'},
    b = ['c1','c2','c3'];
let {item,item1,item2} = a,
    [arrItem,arrItem1] = b,
    [,,arrItem2,arrItem3] = b;
item;       //obj
item1;      //obj1
item2;      //undefined
arrItem;    //c1
arrItem1;   //c2
arrItem2;   //c3
复制代码

没有对比就没有伤害,使用解构赋值可以在一定程度上减少代码量,且代码赋值形式简洁、直观;解构赋值不仅适用于 let 命令, constvar 同样适用。

解构赋值仅允许等号右边的对象是存在遍历器(Iterator)的对象。如下是错误的解构赋值示例:

let [item] = 1;
let [item] = {};
let [item] = NaN;
let [item] = null;
let [item] = false;
let [item] = undefined;
复制代码

解构赋值允许赋值时对变量指定默认值。

//ES5
let obj = {item1: 'test'},
    item1 = obj.item1,
    item2 = obj.item2;
item2;      //空字符串
    
//ES6
let obj = {item1: 'test'},
    { item1='',item2='' } = obj;
item2;      //空字符串
复制代码

比对ES5的赋值形式和ES6的解构赋值,变量 item2 在ES5的赋值形式下,由于 obj 不存在 item2 属性,导致 item2 得到 undefined 的值,而ES6的解构赋值,可在赋值进行时对变量预留默认值,避免赋值的变量得到 undefined 的值;它的效果可理解为

let item1 = obj.item1 || '',
    item2 = obj.item2 || '';
复制代码

解构赋值在解构失败时,若变量没有预留默认值,得到的值也会是undefined。

let obj = {a: 'string'},
    [b,c] = ['test'],
    {d} = obj;
b;      //test
c;      //undefined
d;      //undefined
复制代码

以上情况就是个别变量存在解构失败的示例,变量 b 对应的是 test , c 无对应值, obj.d 不存在,且 cd 未设置默认值,因此 cd 解构失败,得到的值就为 undefined

当且仅当变量对应的取值的数据为undefined时,默认值才会生效

let a = {b: null},
   {b='test'} = a;
b;  // null
let [c='test'] = [undefined];
c;  //test
let [d='test',e='www'] = [NaN,null];
d;  //NaN
e;  //null
复制代码

ES6内部使用严格相等符 === 判断一个值是否等于 undefined ,当且仅当值是 undefined ,默认值才会生效。

若解构赋值中,指定的默认值是一个函数表达式,则该表达式当且仅当在用到的时候才会求值

let fn = () => {
    return '123';
};
let [a=fn(),b=fn()] = [1];
a;      //1
b;      //123
复制代码

在某些场合下,解构赋值也可以将某些对象的方法简便命名调用

let { assign, freeze } = Object;
let a = assign({},{b:1}),
    b = freeze(a);
a;      //{b: 1}
b;      //{b: 1}
复制代码

将一个已被变量声明过的变量用于解构赋值时,需要把解构赋值表达式放在()内

let a = 'test';
{a} = {a: 'obj test'};          //报错:Uncaught SyntaxError: Unexpected token =
({a} = {a: 'obj test'});        //a等于  obj test
复制代码

这是因为在JavaScript解释的过程中,行首是 "{" 的话,JavaScript会把 "{}" 包起来的代码解释为一个代码块,导致语法错误;而我们实际需要执行的是 {a} = {a: 'obj test'} 这样整个赋值过程,因此需要用 "()" 包起来,避免 { 出现在行首。

对对象进行解构赋值时,不要求变量名必须与属性名一致,但命名赋值方式会稍有区别

let man = {name:'john',sex:'male',height:'177cm',weight:'70kg',interest:'climbing'};
let {name: mans_name,sex:sexal,height:tall,job:works='u guess'} = man;
mans_name;      //john
sexal;          //male
tall;           //177cm
works;          //u guess
name;           //Uncaught ReferenceError: name is not defined
复制代码

let {name: mans_name} = man; 代表将 man.name 的值赋值给变量名为 mans_name 的变量,其他变量同理,该赋值形式同样可以设置默认值,如变量 works ;

解构赋值适用于函数参数

function Human({name='',sex='female',age}) {
    if(sex==='male') {
        console.log('u must be a handsome guys!');
    }else if(sex === 'female') {
        console.log('u must be a beauty!');
    }else {
        console.log('exm,r u seriouse?');
    }
    console.log(name);
    console.log(sex);
    console.log)(age);
}
let character = {sex:'male',name:'Allen',age:27}
Human(character); 
//  u must be a handsome guys!
//  Allen
//  male
//  27
复制代码

当参数为undefined时,也会触发默认值生效,如 sex 参数,当不传 sex 参数时, sex 会得到默认值 female

解构赋值同样适用于字符串

let [a,b,c,d] = 'test',
a;          //t
b;          //e
c;          //s
d;          //t
复制代码

解构赋值时,若等号右侧是一个字符串形式的值,解构赋值的处理操作会把右侧字符串转变成类似数组形式的解构进行对变量的解构赋值。 数组对象都具有length属性,因此类数组的对象也必须具有length属性,如下代码块也同样成功执行赋值。

let {length: len} = 'test';
len;        //4
复制代码

对数值类型和布尔型数据进行解构赋值

let {a,toString} = 123;
a;      //undefined
toString === Number.prototype.toString;      //true

let {b,toString} = true;
b;      //undefined
toString === Boolean.prototype.toString;     //true
复制代码

上述两个示例,右侧的值由于可被对象化(Number、Boolean),对象化后均存在 toString 属性,因此 toString 变量等同于相应右侧值对象化后的 prototype.toString 方法。而a、b均是对象化后不存在的属性,因此得到的值就为undefined。

解构赋值的规则是,等号右侧若是对象类型,则直接进行解构赋值,若不是对象类型,会把对象类型转换为对象类型,再进行解构赋值,转换失败,解构赋值失败。

解构赋值的多功能用途

解构赋值能简化变量交换值

let a = 1,b = 2;
[a,b] = [b,a];
a;          //2
b;          //1
复制代码

解构赋值简化对函数返回值取值操作

function test() {
    return {a:'a',b:'b',c:'c'};
};
let {a,b,c} = test();
a;      //a
b;      //b
c;      //c
复制代码

解构赋值简化键值数据获取方式和数据赋值容错写法

let map = new Map();
map.set('test','javacript').set('do','something');
for(let [key,value] of map) {
   console.log(key + ' ' + value);
}
//test javascript
//do something

let obj = {},
   {a='原本是undefined,现在是有个这个字符串的值'} = obj;
a;     //原本是undefined,现在是有个这个字符串的值
复制代码

对import、require引入的模块加载指定的方法或数据

import {Ajax_Interface,Format_Interface} from '~/Interface_Configs.js';
const {RouterConfigs, PageConfigs} = require('Common-Configs');
复制代码

以上所述就是小编给大家介绍的《通俗易懂理解ES6 - 变量的解构赋值》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java多线程编程实战指南(设计模式篇)

Java多线程编程实战指南(设计模式篇)

黄文海 / 电子工业出版社 / 2015-10 / 59.00

随着CPU 多核时代的到来,多线程编程在充分利用计算资源、提高软件服务质量方面扮演了越来越重要的角色。而 解决多线程编程中频繁出现的普遍问题可以借鉴设计模式所提供的现成解决方案。然而,多线程编程相关的设计模式书籍多采用C++作为描述语言,且书中所举的例子多与应用开发人员的实际工作相去甚远。《Java多线程编程实战指南(设计模式篇)》采用Java(JDK1.6)语言和UML 为描述语言,并结合作者多......一起来看看 《Java多线程编程实战指南(设计模式篇)》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具