美文网首页
ES6 解构赋值 & 模板字符串

ES6 解构赋值 & 模板字符串

作者: _ClariS_ | 来源:发表于2019-11-18 15:33 被阅读0次

    一、函数的默认参数

    ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法。

    function log(x, y) {
      y = y || 'World';
      console.log(x, y);
    }
    
    log('Hello') // Hello World
    log('Hello', 'China') // Hello China
    log('Hello', '') // Hello World
    

    ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。

    function log(x, y = 'World') {
      console.log(x, y);
    }
    
    log('Hello') // Hello World
    log('Hello', 'China') // Hello China
    log('Hello', '') // Hello
    

    注意与 Python 的区别,JS 每次调用函数都会重新生成一个array,而 Python 是直接追加到第一次生成的那个array

    JS Python

    二、函数的 rest 参数

    ES5 用arguments来获取函数多余的参数

    function sum(message) {
      let result = 0
      for (let i = 1; i < arguments.length; i++) {
        result += arguments[i]
      }
      return message + result
    }
    sum('结果是', 1, 2, 3, 4, 5, 6) // "结果是21"
    

    ES6 引入rest参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

    function sum(message, ...numbers) {
      let result = numbers.reduce((a, b) => {
        return a + b
      }, 0)
      return message + result
    }
    sum('结果是', 1, 2, 3, 4, 5, 6) // "结果是21"
    

    注意:
    arguments对象是一个“伪数组”。所以为了使用数组的方法,必须使用Array.prototype.slice.call先将其转为数组(还可以使用Array.from或者...)。而rest参数就是一个真正的数组,数组特有的方法都可以使用。

    三、数组的扩展运算符

    扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。

    console.log(...[1, 2, 3])
    // 1 2 3
    
    console.log(1, ...[2, 3, 4], 5)
    // 1 2 3 4 5
    
    [...document.querySelectorAll('div')]
    // [<div>, <div>, <div>]
    

    该运算符主要用于函数调用。

    function push(array, ...items) {
      array.push(...items);
      return array
    }
    push([], ...[1, 2, 3]) // [1, 2, 3]
    
    function add(x, y) {
      return x + y;
    }
    
    const numbers = [4, 38];
    add(...numbers) // 42
    

    注意:只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错。

    (...[1, 2])
    // Uncaught SyntaxError: Unexpected number
    
    console.log((...[1, 2]))
    // Uncaught SyntaxError: Unexpected number
    
    console.log(...[1, 2])
    // 1 2
    

    四、解构赋值

    1. 数组的解构赋值

    以前,为变量赋值,只能直接指定值。

    let a = 1
    let b = 2
    
    oldA = a
    a = b
    b = oldA
    
    console.log(a, b) // 2,1
    

    ES6 的写法可以从数组中提取值,按照对应位置,对变量赋值。

    let a = 1
    let b = 2; // 注意这里有分号
    
    [a, b] = [b, a]
    
    console.log(a, b) // 2,1
    

    解构赋值允许指定默认值。

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

    2. 对象的解构赋值

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

    let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
    foo // "aaa"
    bar // "bbb"
    
    let { baz } = { foo: 'aaa', bar: 'bbb' };
    baz // undefined
    

    对象的解构赋值是下面形式的简写

    let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
    

    也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

    let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
    baz // "aaa"
    foo // error: foo is not defined
    

    上面代码中,foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo

    容易混淆的点:foo什么时候是被赋值的变量?什么时候是匹配模式?

    let { foo } = { foo: 'aaa' }; // 此时 foo 就是被赋值的变量
    
    let { foo: baz } = { foo: 'aaa' }; // 此时 foo 为匹配模式,baz 为被赋值的变量
    

    3. 解构赋值的用途

    (1)交换变量的值
    (2)从函数返回多个值
    (3)函数参数的定义
    (5)函数参数的默认值
    (6)遍历 Map 结构
    (7)输入模块的指定方法

    五、如何合并对象

    Object.assign()

    let obj1 = {
      a: 1,
      b: 2
    }
    let obj2 = {
      a: 3,
      c: 4
    }
    
    let obj3 = Object.assign({}, obj1, obj2)
    console.log(obj3) // {a: 3, b: 2, c: 4}
    

    ...

    let obj1 = {
      a: 1,
      b: 2
    }
    let obj2 = {
      a: 3,
      c: 4
    }
    
    let obj3 = {...obj1, ...obj2}
    console.log(obj3) // {a: 3, b: 2, c: 4}
    

    六、模板字符串

    1. 多行字符串

    传统的 JavaScript 语言,定义多行字符串是这样写的

    /*\后只要有空格就会报错*/ 
    var string = "\
    <div>\
       <p>awsl</p>\
    </div>"
    console.log(string) // <div><p>awsl</p></div>
    
    /*+ 后面允许有空格,但写起来太繁琐*/ 
    var string = "" +
    "<div>" +
       "<p>awsl</p>" +
    "</div>"
    console.log(string) // <div><p>awsl</p></div>
    

    上面两种写法不仅写起来繁琐,而且输出结果里面也不包含回车

    因此,ES6 引入了模板字符串。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

    var string = `
    <div>
       <p>awsl</p>
    </div>
    `
    console.log(string) // 结果包含回车
    /*<div>
         <p>awsl</p>
      </div>*/
    

    2. 字符串里插入变量(插值)

    // 字符串中嵌入变量
    let name = "Bob", time = "today";
    `Hello ${name}, how are you ${time}?`
    

    3. 函数接字符串

    更标准的说法是带标签的模板字符串,这种形式的函数的第一个参数是一个字符串值的数组,其余的参数与表达式相关。

    var name = 'aaa'
    var person = '人'
    var fn = function() {
      console.log(arguments) // [["", "是一个", ""], "aaa", "人"]
      let strings = arguments[0] // ["", "是一个", ""]
      let var1 = arguments[1] // "aaa"
      let var2 = arguments[2] // "人"
      if (var1 === 'aaa') {
        return var1 + strings[1] + '好人'
      } else {
        return var1 + strings[1] + '坏人'
      }
    }
    
    fn`${name}是一个${person}`
    

    styled-component 就是用的这个语法

    参考:
    http://es6.ruanyifeng.com/#docs/function
    http://es6.ruanyifeng.com/#docs/string
    http://es6.ruanyifeng.com/#docs/destructuring
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/template_strings

    相关文章

      网友评论

          本文标题:ES6 解构赋值 & 模板字符串

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