zoukankan      html  css  js  c++  java
  • 解构赋值的用法。

    按照一定模式,从数组和对象中提取,对变量进行赋值,称为解构 
    通过解构我们可以让赋值更优雅便捷

    // 一般赋值
    var a = 1,
        b = 2,
        c = 3;
    //解构赋值
    var [a, b, c] = [1, 2, 3];

    当然不仅仅是var,let和const也可以

    let arr = [1, 2, 3]
    const [a, b, c] = arr;

    语法本质

    实质上这个语法就是一种模式匹配 
    如果等号两边模式相同 
    左边变量就会被赋予相应值 
    所以下面的形式也可以正常赋值

    var [a, [b, [c, d]]] = [1, [2, [3, 4]]];
    console.log(a, b, c, d);//1 2 3 4

    不过我们完全没有必要写这么复杂

    特殊用法

    解构赋值还可以和“…”配合使用 
    如果“…”在等号左边 
    那么就会把剩余的值合并为一个数组 
    这个操作符只能写在最后一个变量前面

    var [left, ...right] = [1, 2, 3, 4, 5];
    console.log(left, right);//1 [2,3,4,5]

    如果“…”在等号右边 
    就是把数组展开再赋值

    var arr = [2, 3, 4];
    var [a, b, c, d] = [1, ...arr];
    console.log(a, b, c, d);//1 2 3 4

    (“…”叫做展开操作符,以后我还会细讲)

    解构失败与不完全解构

    如果没有在匹配中没有对应值,那么它的值就是undefined 
    也就是解构失败 
    等号右边少值

    var [a, b, c] = [1, 2];
    console.log(a, b, c);//1 2 undefined

    与它相对的就是不完全解构 
    等号左边少值

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

    错误解构

    如果等号右边不是数组(不是可遍历解构) 
    就会报错 
    比如说这些情况是不能赋值解构的

    var [foo] = 1/true/NaN/undefined/null/{};

    下面的情况也是不可以的

    var [a, [b]] = [1, 2];

    它可以拆成var a = 1;var [b] = 2; 
    第二个同样不能解构赋值所以会报错

    默认赋值

    可以使用下面这种语法实现默认的赋值

    var [foo = 1] = [];
    console.log(foo); //1

    只有当右侧的值严格等于undefined才会使用默认赋值

    var [foo = 1] = [null];
    console.log(foo); //null

    由于 null !== undefined 
    所以这里foo被赋予null

    惰性赋值

    惰性赋值说的是默认赋值的机制 
    只有在需要使用默认值的时候 
    才会去求值

    function foo(){
        alert(' ');
        return 123;
    }
    var [a = foo()] = [1]; //不弹窗
    console.log(a); //1
    var [a = foo()] = []; //弹窗
    console.log(a); //123

    解构顺序

    解构赋值首先会看右边有没有与之对应的值 
    没有的话从左向右解析

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

    这段代码就相当于

    var a = 1;
    var b = a;

    var [a = b, b = 1] = [];
    console.log(a, b); //undefined 1

    注意 
    如果这里var 换成let就不一样了

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

    这段代码可以看成

    let a = b;
    let b = 1;

    由于let声明没有变量提升 
    所以此时b还未声明就会报错


    可以看看这道题

    var [x1 = 1, y1 = x1] = [];
    var [x2 = 1, y2 = x2] = [2];
    var [x3 = 1, y3 = x3] = [1,2];             
    var [x4 = y4, y4 = 1] = [];   
    console.log(x1,y1);//1 1
    console.log(x2,y2);//2 2
    console.log(x3,y3);//1 2
    console.log(x4,y4);//undefined 1

    同理如果上面的第四行的var换成let会报错

    对象解构

    上面我们通过数组的形式了解了解构赋值 
    其实解构赋值不仅仅可以用数组 
    对象也可以 
    它们类似的地方就不再赘述了

    基本用法

    对象的解构赋值是按照属性名(键)决定的 
    如果没有找到对应的属性,那就赋予undefined

    var {foo, bar, foobar} = {
        foo: 1,
        bar: 2
    }
    console.log(foo, bar, foobar);//1 2 undefined

    对于已经声明过的变量要注意

    var a;
    {a} = {a: 1}; //错误

    浏览器会报错 
    因为js引擎把它理解成了代码块 
    而内部的代码它不认识 
    解决办法就是加上括号 
    这样浏览器就可以知道这是一个表达式

    var a;
    ({a} = {a: 1});

    但是如果我们想要声明的变量与属性名不同怎么办呢 
    我们可以使用另一种模式

    var {foo: a, bar: b, foobar: c = 100} = {
        foo: 1,
        bar: 2
    }
    console.log(a, b, c);//1 2 100

    这相当于声明了a和b变量 
    同样可以使用默认赋值

    字符串解构赋值

    var [a, b, c, d, e] = 'hello';
    console.log(a, b, c, d, e); //h e l l o

    字符串被转化为基本包装对象(类数组对象) 
    所以可以实现

    var {length : len} = 'hello';
    console.log(len); //5

    同理这个类数组对象中有length属性

    基本值解构赋值

    如果等号右边是数字或者布尔值 
    也同样会转化为包装对象

    let {toString: a} = 123;
    let {toString: b} = true;
    console.log( a === Number.prototype.toString); //true
    console.log( b === Boolean.prototype.toString); //true

    但注意null和undefined没有封装对象 
    下面的代码会报错

    let {toString: x } = undefined; //错误
    let {toString: y } = null; //错误

    函数参数的结构赋值

    function add([x, y]) {
        return x + y;
    }
    console.log(add([1, 2]));

    函数参数表面上是一个数组 
    但在传入参数时,数组参数就被结构成变量 x 和 y 
    相当于var [x, y] = [1, 2]


    function foo({x = 0, y = 0} = {}){
        console.log([x, y]);
    }
    foo({x: 1,y: 2}); //[1, 2]
    foo({x: 1}); //[1, 0]
    foo({}); //[0, 0]
    foo(); //[0, 0]
    function bar({x, y} = {x: 0, y: 0}){
        console.log([x, y]);
    }     
    bar({x: 1,y: 2}); //[1, 2]
    bar({x: 1}); //[1, undefined]
    bar({}); //[undefined, undefined]
    bar(); //[0, 0]

    解构赋值的应用

    除了交换变量以外 
    解构赋值还有很多用途

    函数多值返回

    function demo(){
        return [1, 2, 3];
    }
    var [a, b, c] = demo();

    函数定义参数

    function demo({a, b, c}){
        ...
    }
    demo({a: 1, b: 2, c: 3});

    提取JSON数据

    var jsonData= {
        id: 66,
        status: 'OK',
        data: [123, 456]
    }
    let {id, status, data:number} = jsonData;

    转载:https://blog.csdn.net/q1056843325/article/details/53728836

  • 相关阅读:
    C语言 sprintf 函数 C语言零基础入门教程
    C语言 printf 函数 C语言零基础入门教程
    C语言 文件读写 fgets 函数 C语言零基础入门教程
    C语言 文件读写 fputs 函数 C语言零基础入门教程
    C语言 fprintf 函数 C语言零基础入门教程
    C语言 文件读写 fgetc 函数 C语言零基础入门教程
    C语言 文件读写 fputc 函数 C语言零基础入门教程
    C语言 strlen 函数 C语言零基础入门教程
    Brad Abrams关于Naming Conventions的演讲中涉及到的生词集解
    适配器模式
  • 原文地址:https://www.cnblogs.com/manu-yyj/p/9160187.html
Copyright © 2011-2022 走看看