ES6函数参数默认值与解构赋值

673 阅读2分钟

函数参数默认值

// ES6 之前
function foo (x, y) {
  var a = typeof(arguments[0]) !== 'undefined' ? arguments[0] : 1;
  var b = typeof(arguments[1]) !== 'undefined' ? arguments[1] : 2;
  return a + b;
}

console.log(foo()); // -> 3
console.log(foo(3)); // -> 5
console.log(foo(null, 5)); // -> 5
console.log(foo(0, 5)); // -> 5

// ES6
function foo (x = 1, y = 2) {
   return x + y;
}
  • 特殊情况: 参数中的 x 就相当于在函数作用域的顶层 let。

    function bar (x = 2) {
      let x = 3;
      console.log(x);
    }
    bar(); // 报错 SyntaxError: Identifier 'x' has already been declared
    
    let x = 3;
    function foo (x = x) {
      console.log(x);
    }
    foo(); // 报错 ReferenceError: Cannot access 'x' before initialization
    

解构赋值

  • 模式匹配 (结构化赋值):两边结构相同,一一匹配。

    let [a, b, c] = [1, 2, 3];
    console.log(a, b, c); // -> 1 2 3
    
  • 解构失败: 变量多了

    let [a, b, [c], [d, e, [f]]] = [1, 2, [3], [, , [6]]];
    console.log(a, b, c, d, e, f); // -> 1 2 3 undefined undefined 6
    
  • 不完全解构: 值多了

    let [a, b, [c], [, , [f]]] = [1, 2, [3], [4, 5, [6]]];
    console.log(a, b, c, f); // -> 1 2 3 6
    
  • 也可以赋默认值,只有当值为undefined/ 空 时才会走默认值

    let [a, b = 2] = [1];
    console.log(a, b); // -> 1 2
    
    let [a, b = 2] = [1, undefined];
    console.log(a, b); //-> 1 2
    
    let [a, b = 2] = [1, null];
    console.log(a, b); // -> 1 null
    
    let [a, b = 2] = [1, false];
    console.log(a, b); // -> 1 false
    
  • 对象的解构:对象的解构是无序的,结构属性名匹配。

    var name = 'jerome',
        age = 22;
    var obj = {
       name: name,
       age: age,
       say: function () {
              ...
       }
    }
    ES6 中对象的属性名和变量名相同可以简写 方法也可以简写
    var obj= {
       name, 
       age,
       say () {
         ...
       }
    }
    
    let {a, c, b} = {a: 'y', b: 'e', c: 'p'};
    console.log(a, b, c); // -> 'y' 'e' 'p'
    

数组也是特殊的对象,也可以与对象进行解构赋值

let arr = [1, 2, 3];

let {0: first, [arr.length-1]: last} = arr;
console.log(first, last); // -> 1, 3

加深记忆,做出来自己打印。(可以看出来这样写可读性很差,所以在解构中使用数组或对象时慎用)

var x = 200,
    y = 300,
    z = 100;
var obj = {
  x: {
     y: 42
  }, 
  z: {
   y: z
  }
};  
({y: x = {y: y}} = obj);  
({z: y = {y: z}} = obj);  
({x: z = {y: x}} = obj);  
console.log(x, y, z);

解构的隐式转换

const [a, b, c, d, e] = 'hello';
console.log(a, b, c, d, e); // -> h e l l o
let {length: len} = 'hello';
console.log(len); // -> 5
// 会将字符串隐式的转换为类数组进行解构赋值

let {toString: toStr} = 123;
console.log(toStr === Number.prototype.toString); // -> true

let {toString: toStr} = false;
console.log(toStr === Boolean.prototype.toString); // -> true

// 隐式的转换为对应的包装类进行解构赋值

// boolean、number、string 都能进行隐式转换,undefined、null不能进行隐式转换。