原始值和引用值

这里面Java和JavaScript都是只有引用的概念,但是在C/C++里面,就有指针的概念
image.png

  • 原始值: 存储在栈中的简单数据段,即他们的值直接存储在变量访问的位置。

包括:undefined、null、boolean、number、string。

  • 引用值:存储在堆中的对象,即存储在变量处的值是一个指针,只想存储对象的内存处。

包括:object、array、function等

  • 两者的区别:

原始变量及他们的值储存在栈中,当把一个原始变量传递给另一个原始变量时,是把一个栈房间的东西复制到另一个栈房间,且这两个原始变量互不影响。引用值是把引用变量的名称储存在栈中,但是把其实际对象储存在堆中,且存在一个指针由变量名指向储存在堆中的实际对象,当把引用对象传递给另一个变量时,复制的其实是指向实际对象的指针,此时两者指向的是同一个数据,若通过方法改变其中一个变量的值,则访问另一个变量时,其值也会随之加以改变;但若不是通过方法而是通过重新赋值,此时,相当于重新开了一个房间,该值的原指针改变,则另外一个值不会随他的改变而改变。

  1. let s = '基本类型'
  2. let s_test = s
  3. s_test = '改变之后不影响s'
  4. console.log(s)
  5. console.log(s_test)
  6. let arr = ['原始数组值']
  7. arr_test = arr
  8. arr_test[0] = '改变值'
  9. console.log(arr)
  10. console.log(arr_test)
  11. //基本类型
  12. //改变之后不影响s
  13. //[ '改变值' ]
  14. //[ '改变值' ]

原始值 引用值 浅拷贝 深拷贝 - 图2

浅拷贝实现

  1. 直接等号赋值 ```javascript let obj = { ss: ‘ss’, hh: ‘hh’, }

let obj_qian = obj obj_qian.ss = ‘sss’ obj_qian.hh = ‘hhh’ console.log(obj) //{ ss: ‘sss’, hh: ‘hhh’ } console.log(obj_qian) //{ ss: ‘sss’, hh: ‘hhh’ }

  1. <a name="qhGMP"></a>
  2. ### 深拷贝实现
  3. 1. 直接创建一个同类型的数据结构,然后将原值一个个复制过来(数组)
  4. 1. JSON方法(对象)
  5. ```javascript
  6. let obj = {
  7. ss: 'ss',
  8. hh: 'hh',
  9. }
  10. let obj_shen_JSON = JSON.parse(JSON.stringify(obj))
  11. obj_shen_JSON.ss = 'sssss'
  12. obj_shen_JSON.hh = 'hhhhh'
  13. console.log(obj) //{ ss: 'ss', hh: 'hh' }
  14. console.log(obj_shen_JSON) // { ss: 'sssss', hh: 'hhhhh' }

手写深拷贝

  1. let clone = target => {
  2. if (typeof target === 'object') {
  3. let cloneTarget = Array.isArray(target) ? [] : {}
  4. for (const key in target) {
  5. cloneTarget[key] = clone(target[key])
  6. }
  7. return cloneTarget
  8. } else {
  9. return target
  10. }
  11. }
  12. let obj_1 = {
  13. c: 'c',
  14. d: {
  15. d1: 'd1',
  16. d2: 'd2',
  17. },
  18. }
  19. let obj_my = clone(obj_1)
  20. obj_1.c = 'ccccccc'
  21. obj_1.d.d1 = 'dsdddddddd'
  22. console.log(obj_1)
  23. console.log(obj_my)

image.png

Object.assign({}, obj)

  • assign既可以是深拷贝,也可以是浅拷贝
  • Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。
  • 对于Object.assign()而言,如果对象的属性值为简单类型(string,number),通过Object.assign({},srcobj);得到的新对象为深拷贝;如果属性值为对象或其他引用类型,那对于这个对象而言其实是浅拷贝的 ```javascript let obj = { a: ‘a’, b: ‘b’, }

let obj_deep = Object.assign({}, obj) obj.a = ‘aa’ console.log(obj) console.log(obj_deep)

console.log(‘————————————————‘) let obj_obj = { c: ‘c’, d: { d1: ‘d1’, d2: ‘d2’, }, }

let obj_qian = Object.assign({}, obj_obj) obj_obj.c = ‘cc’ obj_obj.d.d1 = ‘d1111’ console.log(obj_obj) console.log(obj_qian) ``` image.png