zoukankan      html  css  js  c++  java
  • ES6中的解构赋值

    1、数组的解构赋值

    1.1、基本用法

     按照“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

    let [a, b, c] = [1, 2, 3];  //a为1,b为2,c为3
    
    let [foo, [[bar], baz]] = [1, [[2], 3]];   //foo: 1  bar: 2  baz: 3
    
    let [ , , third] = ["foo", "bar", "baz"];  //third: "baz"
    
    let [x, , y] = [1, 2, 3];                 //x: 1  y: 3
    
    let [head, ...tail] = [1, 2, 3, 4];      //head: 1  tail: [2, 3, 4]
    
    let [x, y, ...z] = ['a'];                //x: "a"   y: undefined   z: []

    如果左边的值匹配不上,就会被赋值为undefined

    1.2、指定默认值

    解构赋值允许指定默认值。ES6 内部使用严格相等运算符(===),判断等号右边该位置是否有值。所以,等号右边该值严格等于undefined(空也等于undefined),左边的默认值才会生效。

    let [foo = true] = [];  //foo: true
    
    let [x, y = 'b'] = ['a']; // x='a', y='b'
    let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
    
    let [x = 1] = [undefined];  //x:1
    
    let [x = 1] = [null];  //x:null

     1.3、报错情况(等号右边不是数组、默认值引用未定义变量)

    如果等号的右边不是数组(或者严格地说如果不是可遍历的结构),那么将会报错。

    // 报错
    let [foo] = 1;
    let [foo] = false;
    let [foo] = NaN;
    let [foo] = undefined;
    let [foo] = null;
    let [foo] = {};

    默认值可以引用其他的变量,但该变量必须已经声明过,否则将会报错。

    let [x = 1, y = x] = [];     // x=1; y=1
    let [x = 1, y = x] = [2];    // x=2; y=2
    let [x = 1, y = x] = [1, 2]; // x=1; y=2
    let [x = y, y = 1] = [];     // ReferenceError: y is not defined  此时在x用y做默认值时,y还没有声明。

    2、对象的解构赋值

    2.1、基本用法

    对象的解构与数组不太一样,数组的元素是按次序排列的,变量的取值由位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值

    let { foo, bar } = { foo: 'aaa', bar: 'bbb' };  //foo:"aaa"  bar:"bbb"
    
    let { bar, foo } = { foo: 'aaa', bar: 'bbb' };  //foo:"aaa"  bar:"bbb"  次序不影响赋值,变量名才影响
    
    let { baz } = { foo: 'aaa', bar: 'bbb' };       //baz:undefined   变量名匹配不上将会赋值为undefined

    如果变量名与属性名不一致,可以写成这样:

    let { foo: baz } = { foo: 'aaa', bar: 'bbb' };  //baz:"aaa"
    
    let obj = { first: 'hello', last: 'world' };
    let { first: f, last: l } = obj;  //f: 'hello'  l: 'world'

    对象的解构赋值的内部机制,是先找到等号左边的同名属性,然后再赋给左边对应的变量。真正被赋值的是左边同名属性后面的变量,而不是那个同名属性。

    2.2、默认值

    对象的解构也可以指定默认值。

    var {x = 3} = {};  //x: 3
    
    var {x, y = 5} = {x: 1}; //x: 1  y: 5
    
    var {x: y = 3} = {}; //y: 3
    
    var {x: y = 3} = {x: 5}; //y: 5
    
    var { message: msg = 'Something went wrong' } = {}; //msg: "Something went wrong"

    默认值生效的条件是,等号右边对象的属性值严格等于undefined

    var {x = 3} = {x: undefined}; //x: 3
    
    var {x = 3} = {x: null}; //x: null

    2.3、报错情况(给已经定义好的变量赋值可能会报错)

    给已经定义好的变量进行解构赋值有可能会报错:

    let a, b; 
    {a, b} = {a: 123, b: 456};  // 报错显示:Uncaught SyntaxError: Unexpected token =  

    上面的代码将会报错,因为 JS 引擎遇到 {} 会当成一个代码块,语法规定,代码块语句不允许出现在赋值语句左侧。

    所以解构赋值时' { '符号不能出现在一行的最前面。在添加小括号后可以将块语句转化为一个表达式,从而实现整个解构赋值过程。

    let a, b; 
    ({a, b} = {a: 123, b: 456}); 
    console.log(a, b)   // 123 456

     2.4、解构赋值浅拷贝问题

    解构赋值的拷贝是浅拷贝,如果一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。

    let obj = { a: { b: 1 }, c: 100 };
    let { ...x } = obj;  //obj中 a 的值是对象,所以解构赋值时拷贝的是 a 的引用,而 c 的值是简单类型,所以obj.c改变不影响x
    obj.a.b = 2; obj.c = 200;
    console.log(x.a.b,c)     // 2 100

    3、函数参数的解构赋值

    3.1、基本用法

    function add([x, y]){
      return x + y;
    }
    
    add([1, 2]); // 3

    3.2、默认值

    (1)普通参数默认值:

    function show(age, name='www', c=false) {
        console.log(age, name, c);
    }
    show();  //undefined "www" false
    show(12); //12 "www" false
    show(12, 'aaa'); //12 "aaa" false
    show(12, 'aaa', true); //12 "aaa" true

    (2)当函数的参数是一个对象时,默认值的写法:

    function move({x = 0, y = 0} = {}) {
      return [x, y];
    }
    
    move({x: 3, y: 8}); // [3, 8]
    move({x: 3}); // [3, 0]
    move({}); // [0, 0]
    move(); // [0, 0]

    上面代码中,{x=0, y=0} 意思是x,y的默认值分别是0,后面的={}意思是如果函数没有传参时参数默认是{},而且由于前面给x,y默认值了,所以总的来说,参数的默认值是{x=0, y=0}。

    如果没有写后面的={},直接 move() 这样调用将会报错,但其他形式的调用不会有问题。实际上后面的 ={} 才表示默认值。

    注意,下面的写法会得到不一样的结果。

    function move({x, y} = { x: 0, y: 0 }) {
      return [x, y];
    }
    
    move({x: 3, y: 8}); // [3, 8]
    move({x: 3}); // [3, undefined]
    move({}); // [undefined, undefined]
    move(); // [0, 0]

    上面的写法表示的是函数的参数默认是{x:0, y:0},但如果有参数的话即使参数只传x的值,此时默认值便不起作用。

  • 相关阅读:
    Action常见注解的运用
    发现越来越喜欢来博客园了,所以自己也注册了一个!
    jsf 繁体教程下载pdf
    poj3210
    poj3224
    poj3219
    poj3233
    poj3372
    Paper Pal:一个中英文论文及其代码大数据搜索平台
    年轻就该多尝试,教你20小时Get一项新技能
  • 原文地址:https://www.cnblogs.com/wenxuehai/p/10319749.html
Copyright © 2011-2022 走看看