JavaScript中的浅拷贝

Posted LiuJun2Son

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript中的浅拷贝相关的知识,希望对你有一定的参考价值。

1.什么是浅拷贝

例如:根据原始A对象浅拷贝一个新的B对象出来

浅拷贝就是创建一个新对象B,这个对象B有着原始对象A属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是A对象的基本类型的值;如果属性是引用类型,拷贝的就是A对象的内存(引用)地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

浅拷贝只是解决了第一层的拷贝问题,拷贝第一层的基本类型值,以及第一层的引用类型地址,并没有递归拷贝第二层以后的属性。

2.浅拷贝使用方式

1.Object.assign()

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

如何判断一个属性是否可枚举?Object.keys() 可以判断,它返回一个包含所有给定对象自身可枚举属性名称的数组,如果返回的是空数组代表没有可枚举的属性。例如:Number, Boolean, Symbol …是不可枚举的

案例1:根据原始A对象浅拷贝一个新的B对象出来

// 1.Object.assign()  浅拷贝
let A = 
  name:'liujun',
  age:25,
  job:
    name:'web',
    year:4
  

console.log(A) //  name: 'liujun', age: 25, job:  name: 'web', year: 4  
// 1.1 根据原始A对象浅拷贝一个新的B对象出来
let B = Object.assign(,A)
console.log(B) //  name: 'liujun', age: 25, job:  name: 'web', year: 4  

// 1.2 修改A对象的两个name属性。发现B对象的job中的name属性也跟着改动了,说明B对象拷贝A对象job的引用地址
A.name = '刘军'
A.job.name = '前端开发'
console.log('--------------------------------')
console.log(A) //  name: '刘军', age: 25, job:  name: '前端开发', year: 4  
console.log(B) //  name: 'liujun', age: 25, job:  name: '前端开发', year: 4  

总结:只是解决了第一层的拷贝问题,拷贝第一层的基本类型值,以及第一层的引用类型地址

引用类型有 : Object Array Function Date RegExp …

案例2:根据原始 A1 和 A2 浅拷贝一个新的B对象出来

    // 1.Object.assign()  浅拷贝
    let A1 = 'LJ'
    let A2 = 25
    console.log(Object.keys(A1)) // [ '0', '1' ] 可枚举,拷贝成功
    console.log(Object.keys(A2)) // [] 不可枚举,拷贝失败

    // 1.1根据原始A1和A2浅拷贝一个新的B对象出来
    let B = Object.assign(,A1, A2)
    console.log(B) //  '0': 'L', '1': 'J' 

总结:Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象

Number, Boolean, Symbol RegExp …是不可枚举的, 直接传递到 assign 中拷贝会失败,但是可以把它们封装到对象中传递即可以拷贝成功。

2.ES6的…语法

案例1:根据原始A对象浅拷贝一个新的B对象出来

// 1.Object.assign()  浅拷贝
let A = 
  name:'liujun',
  age:25,
  job:
    name:'web',
    year:4
  

console.log(A) //  name: 'liujun', age: 25, job:  name: 'web', year: 4  
// 1.1 根据原始A对象浅拷贝一个新的B对象出来
let B = ...A  // 这个与Object.assign(,A)的功能一样
console.log(B) //  name: 'liujun', age: 25, job:  name: 'web', year: 4  

// 1.2 修改A对象的两个name属性。发现B对象的job中的name属性也跟着改动了,说明B对象拷贝A对象job的引用地址
A.name = '刘军'
A.job.name = '前端开发'
console.log('--------------------------------')
console.log(A) //  name: '刘军', age: 25, job:  name: '前端开发', year: 4  
console.log(B) //  name: 'liujun', age: 25, job:  name: '前端开发', year: 4  

总结:只是解决了第一层的拷贝问题,拷贝第一层的基本类型值,以及第一层的引用类型地址。与Object.assign( , X ) 的功能一样

引用类型有 : Object Array Function Date RegExp …

3.[].slice()

案例1:根据原始A数组浅拷贝一个新的B数组出来

  // 1.使用 [].slice() 浅拷贝
  let A =[
      'arr1',
      [
        'java',
        'web'
      ]
    ]
  console.log(A) // [ 'arr1', [ 'java', 'web' ] ]
  // 1.1根据原始A对象浅拷贝一个新的B对象出来
  let B = A.slice()
  console.log(B) // [ 'arr1', [ 'java', 'web' ] ]

 // 1.2 修改A数组[1][1]的值。发现B数组的中[1][1]的值也跟着改动,说明B数组中二维数组拷贝的是引用地址
  A[0] = '刘军'
  A[1][1] = '前端开发' 
  console.log('--------------------------------')
  console.log(A) // [ '刘军', [ 'java', '前端开发' ] ]
  console.log(B) // [ 'arr1', [ 'java', '前端开发' ] ]

总结:只是解决了第一层的拷贝问题,拷贝第一层的基本类型值,以及第一层的引用类型地址

4.[].concat()

案例1:根据原始A数组浅拷贝一个新的B数组出来

  // 1.使用 [].slice() 浅拷贝
  let A =[
      'arr1',
      [
        'java',
        'web'
      ]
    ]
  console.log(A) // [ 'arr1', [ 'java', 'web' ] ]
  // 1.1根据原始A对象浅拷贝一个新的B对象出来
  let B = [].concat(A)
  console.log(B) // [ 'arr1', [ 'java', 'web' ] ]

 // 1.2 修改A数组[1][1]的值。发现B数组的中[1][1]的值也跟着改动,说明B数组中二维数组拷贝的是引用地址
  A[0] = '刘军'
  A[1][1] = '前端开发' 
  console.log('--------------------------------')
  console.log(A) // [ '刘军', [ 'java', '前端开发' ] ]
  console.log(B) // [ 'arr1', [ 'java', '前端开发' ] ]

总结:只是解决了第一层的拷贝问题,拷贝第一层的基本类型值,以及第一层的引用类型地址

5.编写浅拷贝函数

// 1.简单浅拷贝函数
function shallowCopy(source) 
    var target = ;
    for (var key in source) 
        if (Object.prototype.hasOwnProperty.call(source, key)) 
            target[key] = source[key];
        
    
    return target;


// 2.使用方法
let B = shallowCopy(A)

以上是关于JavaScript中的浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章

javascript中的浅拷贝和深拷贝

JavaScript中的浅拷贝

javascript中的浅拷贝ShallowCopy与深拷贝DeepCopy

Javascript 中的浅拷贝深拷贝是什么?一文带你搞懂,不再犯错

Javascript 中的浅拷贝深拷贝是什么?一文带你搞懂,不再犯错

javascript 没有参考的浅拷贝