美文网首页
《深入理解ES6》读书笔记——5. 解构:使数据访问更便捷

《深入理解ES6》读书笔记——5. 解构:使数据访问更便捷

作者: 弗利萨mom | 来源:发表于2021-02-10 21:30 被阅读0次

    1)对象解构

    (1)对象解构

    对象字面量的语法形式是在一个赋值操作符左边放置一个对象字面量

    (2)解构赋值

    请注意,一定要用一对小括号包裹解构赋值语句,JavaScript引擎将一对开放的花括号视为一个代码块,而语法规定,代码块语句不允许出现在赋值语句左侧,添加小括号后可以将块语句转化为一个表达式,从而实现整个解构赋值的过程。

    (3)没有对应名称的属性值,所以像预期中的那样将它赋值为undefined。

    当指定的属性不存在时,可以随意定义一个默认值,在属性名称后添加一个等号(=)和相应的默认值即可:

    let node = {
        name: 'jim',
        age: 21
    }
    let {name, age, value = true} = node
    console.log(name) // jim
    console.log(age) // 21
    console.log(value) // true
    

    为变量value设置了默认值true,只有当node上么而又该属性值时才生效

    let node = {
        name: 'jim',
        age: 21
    }
    let {name, age = 22, value = true} = node
    console.log(age) // 21
    

    (4)为非同名局部变量赋值

    冒号前的标识符代表在对象中的检索位置,其右侧为被赋值的变量名

    let node = {
        name: 'jim',
        age: 21
    }
    let { name: myName, age: myAge} = node
    console.log(myName) // jim
    console.log(myAge) // 21
    

    当使用其他变量名进行赋值时也可以添加等号和默认值(只需要在变量名后添加等号和默认值即可)

    let node = {
        name: 'jim',
        age: 21
    }
    let { name: myName, age: myAge, value: myValue = false} = node
    console.log(myName) // jim
    console.log(myAge) // 21
    console.log(myValue) // false
    

    (5)嵌套对象解构

    冒号前的标识符代表在对象中的检索位置,其右侧为被赋值的变量名
    如果冒号后面是花括号,则意味着要赋予的最终值嵌套在对象内部更深的层级中。

    let node = {
        type: 'Identifer',
        name: 'foo',
        loc: {
            start: {
                line: 1,
                column: 1
            },
            end: {
                line: 1,
                column: 4
            }
        }
    }
    let { loc: { start } } = node
    console.log(start) // {line: 1, column: 1}
    

    在下面这个版本中,node.loc.start被存储在了新的局部变量myStart中

    let node = {
        type: 'Identifer',
        name: 'foo',
        loc: {
            start: {
                line: 1,
                column: 1
            },
            end: {
                line: 1,
                column: 4
            }
        }
    }
    let { loc: { start: myStart } } = node
    console.log(myStart) // {line: 1, column: 1}
    

    loc不是即将创建的绑定,它代表了在对象中检索属性的位置。在下边这个语句中,右侧只有一对花括号,因而其不会声明任何绑定。

    let node = {
        type: 'Identifer',
        name: 'foo',
        loc: {
            start: {
                line: 1,
                column: 1
            },
            end: {
                line: 1,
                column: 4
            }
        }
    }
    let { loc: {} } = node
    console.log(loc) // Uncaught ReferenceError: loc is not defined
    

    2)数组解构

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

    如果只想取第二个值,secondColor前的逗号是前方元素的运算符

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

    (1)解构赋值

    数组解构赋值还有个独特的用例:交换两个变量的值

    let a = 1,
        b = 2;
    [a, b] = [b, a];
    console.log(a, b) // 2 1
    

    (2)默认值

    let colors = ['red', 'yellow']
    let [ firstColor, secondColor = 'blue'] = colors
    console.log(firstColor, secondColor) // red yellow
    let colors1 = ['red']
    let [firstColor1, secondColor1 = 'blue'] = colors1
    console.log(firstColor1, secondColor1) // red blue
    

    (3)嵌套数组解构

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

    (4)不定元素

    在数组中,可以通过...语法将数组中的其余元素赋值给一个特定的变量

    let colors = ['red', 'yellow', 'blue', 'green']
    let [ firstColor, ...restColors ] = colors
    console.log(firstColor, restColors) // red ["yellow", "blue", "green"]
    

    可以克隆数组

    let colors = ['red', 'yellow', 'blue', 'green']
    let [ ...clonedColors ] = colors
    console.log(clonedColors) // ["red", "yellow", "blue", "green"]
    

    注意,在被解构的数组中,不定元素必须为最后一个条目,否则会导致程序抛出语法错误。

    3)混合解构

    let node = {
        type: 'Indentifier',
        name: 'foo',
        loc: {
            start: {
                line: 1,
                column: 1
            },
            end: {
                line: 1,
                column: 4
            }
        },
        range: [0, 4]
    }
    let { loc: {start}, range: [startIndex] } = node
    console.log(start, startIndex) // {line: 1, column: 1} 0
    

    这里面的loc和range仅代表它们在node中所处的位置(也就是该对象的属性)
    不需要再遍历数组了

    4)解构参数

    function setCookie (name, value, options) {
        options = options || {}
        let secure = options.secure,
            path = options.path,
            domain = options.domain,
            expires = options.expires
        console.log(secure, path, domain, expires) // true undefined undefined 6000
    }
    setCookie("type", "js", { secure: true, expires: 6000 })
    

    上面这个例子无法清晰的了解函数预期的参数,需要阅读函数体。
    下面用解构参数重写一下

    function setCookie (name, value, { secure, path, domain, expires}) {
        console.log(secure, path, domain, expires) // true undefined undefined 6000
    }
    setCookie("type", "js", { secure: true, expires: 6000 })
    

    好处是对于调用次函数的使用者,解构参数变得清晰了。

    (1)必须传值的解构参数

    function setCookie (name, value, { secure, path, domain, expires}) { // Uncaught TypeError: Cannot destructure property 'secure' of 'undefined' as it is undefined.
        console.log(secure, path, domain, expires)
    }
    setCookie("type", "js")
    

    如果不传第三个参数会报错。
    当调用setCookie()函数时,Javascript引擎实际上是做了这些事情:

    function setCookie (name, value, options) {
        let { secure, path, domain, expires } = options
    }
    setCookie("type", "js")
    

    如果解构赋值表达式的右侧为null或undefined,则程序会报错

    let { first, second } = null // Uncaught TypeError: Cannot destructure property 'first' of 'null' as it is null.
    
    let { name, age } = undefined // Uncaught TypeError: Cannot destructure property 'name' of 'undefined' as it is undefined.
    

    如果希望将解构参数东以为可选的,那就必须为其提供默认值来解决这个问题:

    function setCookie (name, value, { secure, path, domain, expires } = {}) {
        console.log(secure, path, domain, expires) // undefined undefined undefined undefined
    }
    setCookie("type", "js")
    

    这样即使在调用时未传第3个参数,程序也不会报错。

    (2)解构参数的默认值

    function setCookie (name, value, { secure = true, path = '/', domain = 'example.com', expires = 4000 } = {}) {
        console.log(secure, path, domain, expires) // true "/" "example.com" 4000
    }
    setCookie("type", "js")
    
    function setCookie (name, value, { secure = true, path = '/', domain = 'example.com', expires = 4000 } = { secure: true, path: '/', domain: 'example.com', expires: 4000 }) {
        console.log(secure, path, domain, expires) // true "/" "example.com" 4000
    }
    setCookie("type", "js")
    

    第一个对象字面量是解构参数,第二个为默认值
    下面改写下,消除冗余代码

    const setCookieDefaults = { secure: true, path: '/', domain: 'example.com', expires: 4000 }
    function setCookie (name, value, { secure = setCookieDefaults.secure, path = setCookieDefaults.path, domain = setCookieDefaults.domian, expires = setCookieDefaults.expires } = setCookieDefaults) {
        console.log(secure, path, domain, expires) // true "/" "example.com" 4000
    }
    setCookie("type", "js")
    

    相关文章

      网友评论

          本文标题:《深入理解ES6》读书笔记——5. 解构:使数据访问更便捷

          本文链接:https://www.haomeiwen.com/subject/tgokxltx.html