美文网首页
14 JavaScript References VS Copy

14 JavaScript References VS Copy

作者: 地平线0530 | 来源:发表于2018-12-20 12:58 被阅读0次

    效果

    效果图

    Demo
    Github

    知识点

    • 数组的复制
      • arr.slice()
      • [].concat(arr)
      • Array.from(arr)
      • [...arr]
    • 对象的复制
      • Object.assign({}, obj, {x: xx})
      • JSON.parse(JSON.stringify(obj))

    笔记

    在复制 Array 和 Object 类型数据的时候,不能通过直接赋值的办法,如下:

    // Array
    const arr1 = ['a', 'b', 'c', 'd']
    const arr2 = arr1
    
    console.log(arr1, arr2)  // ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd']
    
    arr2[2] = 'x'
    
    console.log(arr1, arr2)  // ['a', 'b', 'x', 'd'], ['a', 'b', 'x', 'd']
    
    // Object
    const obj1 = {
      name: '令狐冲',
      age: 31
    }
    const obj2 = obj1
    
    console.log(obj1, obj2)  // {name: '令狐冲', age: 31}, {name: '令狐冲', age: 31}
    
    obj2.name = '任盈盈'
    
    console.log(obj1, obj2)  // {name: '任盈盈', age: 31}, {name: '任盈盈', age: 31}
    

    这样的结果显然不是我们想要的,原因就是在 JavaScript 中直接将对象赋值给变量,只是对它的引用,类似于 C 语言中的指针,为了应对这种特性,我们有以下几种解决办法:

    拷贝数组

    • 方法一
      const arr1 = ['a', 'b', 'c', 'd']
      
      // 利用 slice() 方法返回一个新数组,而不会改变原数组
      const arr2 = arr1.slice()
      
    • 方法二
      // 利用 concat() 方法,以一个空数组拼接原数组
      const arr3 = [].concat(arr1)
      
    • 方法三
      // 利用 ES6 提供的新方法 Array.from(),创建新数组
      const arr4 = Array.from(arr1)
      
    • 方法四
      // 利用扩展语句
      const arr5 = [...arr1]
      
      但是展开语法有个问题,就是它只能做拷贝一层的浅拷贝,比如:
      const item1 = ['a', 'b', 'c', [1, 2, 3]]
      const item2 = [...item1]
      
      console.log(item1)  // ['a', 'b', 'c', [1, 2, 3]]
      console.log(item2)  // ['a', 'b', 'c', [1, 2, 3]]
      
      item2[1] = 'x'
      console.log(item1)  // ['a', 'b', 'c', [1, 2, 3]]
      console.log(item2)  // ['a', 'x', 'c', [1, 2, 3]]
      
      item2[3][1] = 'oo'
      console.log(item1)  // ['a', 'b', 'c', [1, 'oo', 3]]
      console.log(item2)  // ['a', 'x', 'c', [1, 'oo', 3]]
      

    拷贝对象

    • 方法一
      // 使用 Object.assign() 方法
      const obj1 = { name: '令狐冲', age: 31 }
      const obj2 = Object.assign({}, obj1)
      
      const obj3 = Object.assign({}, obj1, {'剑法': '独孤九剑', '内功': '易筋经'})
      
      console.log(obj1)  // { name: '令狐冲', age: 31 }
      console.log(obj2)  // { name: '令狐冲', age: 31 }
      console.log(obj3)  // { name: '令狐冲', age: 31, '剑法': '独孤九剑', '内功': '易筋经' }
      
      但是,此方法如同数组的展开语法一样,只是浅拷贝,如下:
      const person = { 
        name: '令狐冲',
        age: 31,
        '武功': {
          '剑法': '独孤九剑',
          '内功': '易筋经',
          '内功2': '吸星大法'
        }
      }
      
      const p2 = Object.assign({}, person)
      p2['武功']['剑法'] = '辟邪剑法'
      
      console.log(person['武功']['剑法'])  // '辟邪剑法'
      
    • 方法二
      // 先将对象转换为 JSON 对象,在转换为 Object
      const person = { 
        name: '令狐冲',
        age: 31,
        '武功': {
          '剑法': '独孤九剑',
          '内功': '易筋经',
          '内功2': '吸星大法'
        }
      }
      
      const p3 = JSON.parse(JSON.stringify(person))
      

    相关文章

      网友评论

          本文标题:14 JavaScript References VS Copy

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