es6新特性之解构

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tank_in_the_street/article/details/79019070

        在es6之前,如果我们想把一个对象或者一个数组里的某个值存储到某个变量里,我们通常是这样做的:

let object = {
    a: 'aaa',
    b: 'bbb'
}
let a = object.a, b = object.b
        但是这样做有一个问题,就是如果这个对象有很多个属性,我们要拿很多个属性的变量来存储的话,那就要写很多个变量,非常的繁琐。在es6里面,我们可以通过解构来优雅的解决这个问题:

let object = {
    a: 'aaa',
    b: 'bbb'
}
let {a, b} = object
        在这里,花括号里的变量名一定要与对象object里的属性名相对应,这样它才能够读取object里相对应的属性值。如果在花括号里的变量名与所要对应的对象里的属性名不相同,则该变量的返回值是undefined。如:

let object = {
    a: 'aaa',
    b: 'bbb'
}
let {a, c} = object  //c变量的返回值为undefined
        使用解构的时候一定要在他的左侧赋值,如果不赋值则会报错。如:

let object = {
    a: 'aaa',
    b: 'bbb'
}
let {a, b}
        我们也可以利用解构来给某个已经声明的变量赋值:

let object = {
    a: 'aaa',
    b: 'bbb'
}, a = 'ccc', b = 'ddd';
({a, b} = object)
        在上面的代码中,如果把小括号里的代码注释掉,则我们的a和b这两个变量返回的值是ccc和ddd,但是如果不注释小括号里的代码的话,则将a和b变量进行重新的赋值。

        需要注意的是,解构表达式右侧的值不能为null或者是undefined,否则会报错。如果我们的解构表达式里声明了多个变量,但是有一些变量是在那个对象里找不到与之对应的属性时,这个变量的值为undefined,在这种情况下我们可以给那个变量赋予初始值,如:

let object = {
    a: 'aaa',
    b: 'bbb'
}
let {a, b, c = 'ccc'} = object
        在上面的情况里,限死了变量名必须与所对应的对象属性名相同,但是在实际开发中,我们可能想用不同的变量名来代表某些特定的东西,这个时候我们可以用下面的方法来给变量名改名:

let object = {
    a: 'aaa',
    b: 'bbb'
}
let {a: c, b: d,} = object
        在这里,相当于将object.a的值赋值给了c,将object.b的值赋值给了d,这个时候如果你在控制台里输入a会报错,因为并没有声明a这个变量,相反,你输入c它会输出object.a的值。

        但是一切都不是一帆风顺的,如果对象里面嵌套对象,而我们想要拿到嵌套对象里面的某个属性的时候,这样子怎么用嵌套来做呢?举个例子,下面是两重嵌套和三重嵌套的情况:

let object = {
    a: {
        c: 'ccc',
        d: 'ddd'
    },
    b: 'bbb'
}
let {a} = object

let object = {
    a: {
        b: {
            c: 'ccc',
            d: 'ddd'
        }
    },
    e: 'eee'
}
let {a: {b}} = object
        两重嵌套时,我们可以像之前一样赋值给某个变量就可以了,但是在三重嵌套的时候,写法就看起来比较怪。还记得上面的给变量起另一个变量名吗,其实在

let {a: {b}} = object一句里,在花括号{a: {b}}的内部,冒号左边的值赋值给了冒号右边的值,就变相的变成了let {b} = a,而a是等于let {a} = object的。这与平常我们见到的赋值方式有很大的不同,在对象里通常是左边的属性等于右边的值,而在解构中刚好相反,这是需要注意的。

        除了对象的解构外,我们还能对数组进行解构。数组的解构和对象的解构类似,只不过要把花括号改成中括号,下面来举一些实例:

let object = ['a', 'b', 'c']
let [aa, bb] = object

let object = ['a', 'b', 'c']
let [bb, aa] = object
        上面则两个a和b输出的结果是不同,数组的解构不像对象的解构,数组的解构里,变量是要按顺序的,并且数组解构里,变量名可以不用与数组里的元素值相对应。

        我们可以利用上面的方法来实现变量的交换。一般的,如果我们想要两个变量的值互换的话,是需要第三个变量来作为存储的,如:

let a = 1, b = 2, tmp
tmp = a
a = b
b = tmp
        但是有了解构,我们可以用更加方便的方法来实现:

let a = 1, b = 2
[a, b] = [b, a]
        这里通过两行代码,连中间变量都不用,比较方便快捷的将a、b两个变量的值互换,省时省力。

        如果我们只是想拿某个元素来存储的话,可以用下面这种比较灵活的方法:

let object = ['a', 'b', 'c']
let [, , cc] = object
        这种方法,逗号作为占位符,我们可以通过这种方法来拿取第三个元素,从而不需要指定cc前面的变量名。

        既然上面都有嵌套对象的解构,那么我们嵌套数组是如何解构呢。嵌套数组的解构比嵌套对象的解构还要简单理解。下面用二重数组和三重数组来举例:

let object = ['a', ['c', 'd'], 'b']
let [aa, [bb]] = object

let object = ['a', ['c', 'd', ['e', 'f']], 'b']
let [aa, [, , [bb]]] = object
        在二重循环里,由于第二个变量所代表的是object[1],而第二个变量里又套了个解构表达式,所以就能解构出object[1][0]的值。同理,三重循环也是一样的道理,解构出object[1][2][0]的值。

        像上面的三重循环,我现在改成下面这样写,bb输出的东西又是不同:

let object = ['a', ['c', 'd', ['e', 'f']], 'b']
let [aa, [, ...[bb]]] = object
        在[, ...[bb]]这里,逗号作为一个占位符,表示的是object[1][0]元素的值,而...[bb]这里的...,作为es6的新特性,表示的是数组余下的内容,所以这个时候,...[bb]其实是等于['d', ['e', 'f']],而这个...[bb]里的第一个元素,自然就是d,所以会输出d。

        在实际生活中,可能遇见的情况比较复杂。如果一个对象里不仅有对象,还有数组的时候,那我们如何混合解构呢?我现在举一个实例:

let node = {
    a: 'aaa',
    b: 'bbb',
    c: {
        d: {
            i: 'iii',
            j: 'jjj'
        },
        e: {
            i: 'III',
            j: 'JJJ'
        }
    },
    f: ['ggg', 'hhh']
}
let {
    c: {d},
    f: [first]
} = node
        在这种情况下,我们可以像解构对象那样先获取所对应属性的值,然后根据这个值是对象还是数组来进行进一步的解构。

        解构除了可以用在数组和对象上,我们也可以用在函数里参数的解构。一般的,如果我们给一个函数的参数传递一个对象,在函数里想要获取对象里面的属性,一般是这样子操作的:

function ha(name, value, options) {
    options = options || {}
    let a = options.a,
        b = options.b,
        c = options.c,
        d = options.d
}
ha('name', 'value', {
    a: 'aaa',
    b: 'bbb',
    c: 'ccc',
    d: 'ddd'
})
        但是如果利用解构来做的话,则方便了很多,如:

function ha(name, value, {a, b, c, d}) {

}
ha('name', 'value', {
    a: 'aaa',
    b: 'bbb',
    c: 'ccc',
    d: 'ddd'
})

        仅仅只需上面这要做,简化赋值的操作,如果函数里的解构参数有不能与要传入的对象的属性匹配的话,则匹配不了的参数会返回undefined。其实参数的解构只是把对象的解构放到函数的参数里执行而已。如果函数里的解构参数没有被传入,如:

function ha(name, value, {a, b, c, d}) {

}
ha('name', 'value')
        则会报错,为了解决这个问题,我们只需这样做:

function ha(name, value, {a, b, c, d} = {}) {

}
ha('name', 'value')
        这样就等于赋予它们一个默认的值为undefined。如果想赋予其他的值,你如果天真的想这样做:

function ha(name, value, {a = 'aaa', b = 'bbb', c = 'ccc', d = 'ddd'}) {

}
ha('name', 'value')
       那就会报错,原因是调用它的函数里没有传入解构。为了解决这个问题,需要传入的解构按照你的函数的解构的写法来写,如:

function ha(name, value, {a = 'aaa', b = 'bbb',
                c = 'ccc', d = 'ddd'} = {a: 'aaa', b: 'bbb', c: 'ccc', d: 'ddd'}) {
}
ha('name', 'value')
        这样子就不会报错了。

猜你喜欢

转载自blog.csdn.net/Tank_in_the_street/article/details/79019070