《深入理解ES6》-5-解构-笔记

解构

  • 意义:
    • 从对象或数组中获取特定数据并赋值给变量

对象解构

  • 在赋值操作符左侧放置一个对象字面量
        let node = {
            type: "id",
            name: "shaun"
        };
        let {type, name} = node;
        console.log(type);  // "id"
        console.log(name);  // "shaun"
  • 不要忘记初始化程序(等号右侧的值)
    • 解构赋值表达式(=右侧的表达式)如果为null或undefined会抛出错误
    • 语法错误
            // 解构
            var {type, name}; // uncaught SyntaxError
            let {type, name}; // uncaught SyntaxError
            const {type, name}; // uncaught SyntaxError

            // 声明
            const name; // uncaught SyntaxError
            let name; // undefined

解构赋值

  • 变量赋值时解构赋值
    * 一定要用小括号将解构赋值语句包裹
    - js将一对开放的花括号视作一个代码块
    - 语法规定,代码块不允许出现在赋值语句左侧
    - 添加小括号可以将块语句转化为表达式,实现解构赋值
            let node = {
                type: "id",
                name: "shaun"
            },
            type = "cls",
            name = "david";

            // 解构赋值(注意括号)
            ({type, name} = node);

            // 变量的值被修改
            console.log(type);  // "id"
            console.log(name);  // "shaun"
  • 任意小括号都能触发解构赋值
            let node = {
                type: "id",
                name: "shaun"
            },
            type = "cls",
            name = "david";

            // 函数被调用时,传入的value等同为'info({type, name} = node)'中=右侧的值,即node
            function info(value) {
                console.log(value === node); // true
            }

            // 触发解构赋值
            info({type, name} = node);

            // 变量的值被修改
            console.log(type);  // "id"
            console.log(name);  // "shaun"

默认值

  • 若指定的局部变量名在对象中不存在,则会被赋值undefined
        let node = {
            type: "id",
            name: "shaun"
        };

        let {type, name, value} = node;

        console.log(type);  // "id"
        console.log(name);  // "shaun"
        console.log(value);  // "undefined"
  • 指定默认值
        let node = {
            type: "id",
            name: "shaun"
        };

        let {type, name, value = true} = node;

        console.log(type);  // "id"
        console.log(name);  // "shaun"
        console.log(value);  // true

为非同名局部变量赋值

  • 指定赋值来源
            let node = {
                type: "id",
                name: "shaun"
            };

            let {type: localType, name: localname} = node;

            console.log(localType);  // "id"
            console.log(localname);  // "shaun"
  • 增加默认值
            let node = {
                type: "id"
            };

            let {type: localType, name: localname = "bar"} = node;

            console.log(localType);  // "id"
            console.log(localname);  // "bar"

嵌套对象解构

  • 将对象拆解以获取想要的信息
    • 解构模式中用了花括号,意义是:
      • 找到loc属性后,深入一层找start属性
    • 冒号前的标识符都代表在对象中检索的位置
    • 冒号后为被赋值的变量名
    • 若冒号后为花括号,意味着要赋予的最终值嵌套在对象内部更深的层级中
        let node = {
            type: "id",
            name: "shaun",
            loc: {
                start:{
                    line: 1,
                    column: 2
                },
                end: {
                    line: 3,
                    column: 6
                }
            }
        };

        let {loc: {start}} = node;

        console.log(start.line);  // "1"
        console.log(start.column);  // "2"
  • 使用一个与对象属性名不同的局部变量名
        let node = {
            type: "id",
            name: "shaun",
            loc: {
                start:{
                    line: 1,
                    column: 2
                },
                end: {
                    line: 3,
                    column: 6
                }
            }
        };

        // 提取node.loc.start
        // node.loc.start的值被储存在新的局部变量localStart中
        let {loc: {start: localStart}} = node;

        // 未声明任何变量,没有任何作用
        // 不会声明任何绑定
        // 未来可能会被废弃的功能
        // 可以用默认值来完成目的:let {loc: {} = {a:true}} = node;
        let {loc: {}} = node;

        console.log(localStart.line);  // "1"
        console.log(localStart.column);  // "2"

数组解构

  • 使用数组字面量
  • 解构操作全部在数组内部完成
  • 不会像对象解构那样运用对象的命名属性
            let colors = [ "red", "green", "blue" ];
            let [ firstColor, secondColor ] = colors;

            // 数组解构中通过值在数组中的位置进行选取,将其储存在任意变量中
            // 未显式声明的元素都会直接被忽略(如"blue")
            // 结构过程中,原数组不发生任何变化
            
            console.log(firstColor);  // "red"
            console.log(secondColor);  // "green"
  • 可以直接省略元素,只为感兴趣的元素提供变量名
            let colors = [ "red", "green", "blue" ];

            // 逗号只是占位符
            let [ , , thirdColor ] = colors;

            // 数组解构中通过值在数组中的位置进行选取,将其储存在任意变量中
            // 未显式声明的元素都会直接被忽略(如"blue")
            // 结构过程中,原数组不发生任何变化
            console.log(thirdColor);  // "blue"
  • 与对象解构一样,通过var, let, const声明数组解构的绑定时,必须提供初始化程序(=右侧)

解构赋值

  • 不需要小括号包裹表达式
            let colors = [ "red", "green", "blue" ],
                firstColor = "gray", 
                secondColor = "black";

            [ firstColor, secondColor ] = colors;

            // 数组解构中通过值在数组中的位置进行选取,将其储存在任意变量中
            // 未显式声明的元素都会直接被忽略(如"blue")
            // 结构过程中,原数组不发生任何变化
            console.log(firstColor);  // "red"
            console.log(secondColor);  // "green"
  • 用法实例:交换变量的值
    • ES5中需要一个中间值转换
                let a =1, 
                    b = 2, 
                    tmp;
                tmp = a;
                a = b;
                b = tmp;
                console.log(a);  // 2
                console.log(b);  // 1
 + ES6可以直接用解构
                let a =1, 
                    b = 2;

                // 左侧是数组解构模式
                // 右侧是一个为交换临时创建的数组字面量
                // 执行过程中是先解构临时数组,将b, a的值复制到左侧的前两个位置
                // 结果就是交换了他们的值
                [a, b] = [b, a];
                console.log(a);  // 2
                console.log(b);  // 1

默认值

  • 当指定位置的属性不存在或者其值为undefined,要用默认值
            let colors = [ "red" ];

            let [ firstColor, secondColor = "green" ] = colors;

            console.log(firstColor);  // "red"
            console.log(secondColor);  // "green"

嵌套数组解构

  • 在原有数组模式中插入另一个数组模式,即可解构深入到下一个层级
            let colors = [ "red", ["green", "blue"] ];

            // secondColor变量取["green", "blue"]的第一个位置的值
            let [ firstColor, [ secondColor ] ] = colors;

            console.log(firstColor);  // "red"
            console.log(secondColor);  // "green"

不定元素

  • 数组中可以通过不定元素(...rest)将数组中其余元素赋值给一个特定的变量
  • 不过不定元素必须为最后一个条目
  • 在其后面继续添加逗号,会报错
            let colors = [ "red", "green", "blue" ];

            let [ firstColor, ...restColor ] = colors;

            console.log(firstColor);  // "red"
            console.log(restColor.length);  // 2
            console.log(restColor[0]);  // "green"
            console.log(restColor[1]);  // "blue"
  • 用法实例:复制(克隆)数组
    • ES5中用concat()
                let colors = [ "red", "green", "blue" ];

                let clonedColors = colors.concat();

                console.log(clonedColors);  // "[red, green, blue]"
 + ES6可以直接用解构
                let colors = [ "red", "green", "blue" ];

                let [ ...clonedColors] = colors;

                console.log(clonedColors);  // "[red, green, blue]"

混合解构

  • 可以混合使用对象和数组的解构来创建更复杂的表达式,提取你想要的信息
  • 此种方法对从json中提取数据非常有用,不需要再遍历整个json数据
  • 下面代码中let { loc: {start}, range: [startIndex] } = node;的'loc:'和'range:'只是代表他们在node中所处的位置(即该对象的属性)
            let node = {
                type: "id",
                name: "shaun",
                loc: {
                    start: {
                        line: 1,
                        column: 2
                    }
                },
                range: [0, 3]
            };

            let { loc: {start}, range: [startIndex] } = node;

            console.log(start.line);  // 1
            console.log(start.column);  // 2
            console.log(startIndex);  // 0

解构参数

  • 解构参数支持所有解构特性:默认值,混合对象和数组的结构模式,以及非同名变量存储信息等
  • 解构可以用在函数传递参数的过程中
    • 普通模式:
                function setCookie(name, value, options) {
                    options = options || {};
                    let secure = options.secure,
                        path = options.path,
                        domain = options.domain,
                        expires = options.expires;
                    // to do...
                }

                // 第三个参数自动映射到options参数内
                setCookie("type", "js", {secure: true, expires: 6000});
+ 解构模式:
                function setCookie(name, value, {secure, path, domain, expires}) {
                    // to do...
                }
                
                setCookie("type", "js", {secure: true, expires: 6000});

必须传值的解构参数

  • 以上代码第三项为解构参数,如果调用函数时不提供被解构的参数,会报错,如:
            function setCookie(name, value, {secure, path, domain, expires}) {
                // to do...
            }
            
            setCookie("type", "js"); // 报错
  • 此时,可以用默认值来解决:
            function setCookie(name, value, {secure, path, domain, expires} = {}) {
                // to do...
            }
            
            setCookie("type", "js"); // 正常

解构参数的默认值

  • 冗余情况(默认参数):
            function setCookie(name, value, 
                {
                    secure = false, 
                    path = "/", 
                    domain = "example.com", 
                    expires = new Date(Date.now() + 360000000)
                } = {
                    // 以下为默认参数
                    secure = false, 
                    path = "/", 
                    domain = "example.com", 
                    expires = new Date(Date.now() + 360000000)
                }
            ) {
                // to do...
            }
            
            setCookie("type", "js"); // 正常
  • 精简情况:
            // 修改参数便利,自动同步,还可以直接用这个对象来为每一个绑定设置默认参数
            const setCookieDefaults = {
                secure = false, 
                path = "/", 
                domain = "example.com", 
                expires = new Date(Date.now() + 360000000)
            }

            function setCookie(name, value, 
                {
                    secure = setCookieDefaults.secure, 
                    path = setCookieDefaults.path, 
                    domain = setCookieDefaults.domain, 
                    expires = setCookieDefaults.expires
                } = setCookieDefaults
            ) {
                // to do...
            }
            
            setCookie("type", "js"); // 正常
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 1.数组的解构赋值 2.对象的解构赋值 3.字符串的解构赋值 4.数值和布尔值的解构赋值 5.函数参数的解构赋值 ...
    卞卞村长L阅读 914评论 0 0
  • 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring...
    嘉奇呦_nice阅读 788评论 0 2
  • 《ECMAScript6 入门》阮一峰 读书笔记 let和constlet声明的变量仅在块级作用域内有效,var声...
    亲爱的孟良阅读 705评论 1 2
  • 1.属性的简洁表示法 允许直接写入变量和函数 上面代码表明,ES6 允许在对象之中,直接写变量。这时,属性名为变量...
    雨飞飞雨阅读 1,123评论 0 3
  • 一. 我有一位朋友,暂且叫他小M。他是我在老家读初中认识的,对于学习不断退步的我来说,小M和煦阳光的笑容和...
    我的名字很肤浅阅读 291评论 0 0