深浅拷贝 学习总结
封面画师:唏嘘的星辰  p站ID:13312138
栈空间和堆空间
栈空间:一般基本数据类型存放在栈里面,栈类似于电梯结构,先进后出的特点堆空间: 一般引用类型存储在堆空间,严格来说,把变量保存在栈空间,把值保存在堆空间,堆类似于排队买饭,先进先出的特点
基本数据类型值传递
在赋值的时候,把值本身复制一份,赋值给新变量,修改其中一个时候,另外一个不会变化,类似于复制和粘贴
var a  = 10 
var b = a //赋值
a = 20 // 修改a不会影响到b
console.log(b)  //10复杂类型,引用类型 引用传递
在赋值的时候,把指针复制一份,把复制的指针赋值给新变量,新旧指针指向的是同一个内存地址,这个俩个变量指向的是同一个数据,修改其中之一,另外一个会跟着修改
// 指针:指向内容的地址就是指针
var arr = [1,2,3]
var arr1 = arr
arr[0] = "好"
console.log(arr1) // ["好",2,3]赋值封装
基本数据类赋值场景:变量赋值,函数传参
引用类型类赋值场景:变量赋值,函数传参
function f1(a){
    a = 10 
    console.log(a,"------------") //10
} 
var num1 = 200
  f1(num1) //把实参赋值给形参  a=num1
console.log(num1,"+++++++") //200
function f2(arr3){
    arr3[0]="好"
    console.log(arr3,"_____________") //["好",2,3]
}
var newArray = [1,2,3]
f2(newArray) // arr3 = newArray
console.log(newArray,"???????????")//["好",2,3]深浅拷贝
基本数据类型拷贝
修改其中一个另外一个不会跟着变化
复杂数据类型拷贝
深浅拷贝:仅限于引用类型的数据,(不严谨的说:值传递天生深拷贝)深拷贝: 修改其中一个另外一个不会受到影响浅拷贝: 修改其中一个另外一个会受到影响 出现场景直接赋值就是浅拷贝
实现深拷贝
var obj = {
  name:'zhangsna',
  age:10,
}
// 自己实现深拷贝的方式 把o拷贝一个新内存
//  没有实现多层拷贝
function deepCopy(o){
  var newO = {} //这个就是新内存
  for (const key in o) {
    // 遍历o对象所有属性和属性值添加到新对象里面
    newO[key] = o[key]  // newO["name"] = zhangsan  newO["age"] = 10
  }
  return newO 
}
var n1 = deepCopy(obj)
obj.name = "张三" // n1 没有受到该句的影响
console.log(n1,obj)使用json的相关的API进行深拷贝
var o1 = {
  name:"11",
  age:10,
  study:{
    book:"前端页面开发"
  }
}- 对o1进行转成字符串 - var s1 = JSON.stringify(o1)- console.log(s1)
- 再对字符串进行转成对象 - var o2 = JSON.parse(s1)
- 修改o1 看看是否影响到o2 - o1.study.book = "java"- console.log(o1,o2) // 不会影响
完整深拷贝
// 深拷贝
var obj = {
  name:"zs",
  age:10,
  gf:{
    name:"lis",
    age:18
  }
}
// typeof 10  ==number
// typeof "1" == string
// typeof {}  == object
// typeof []  == object
console.log(typeof [])
//思路:先创建一个空对象,遍历源对象每一层把每一层的属性拷贝到新对象里面
function deepCopy(o){
  // 如果o是对象创建空对象,如果o是数组创建一个空数组
  // Array.isArray(o) 判断o是不是一个数组
  var newObj = Array.isArray(o)?[]:{}
  if(o && typeof o =='object'){
    // 如果o存在,并且o的typeof值是object
    // 遍历o对象
    for (const key in o) {
      // 判断对象是否key 如果存在取值
      if (Object.hasOwnProperty.call(o, key)) {
        const element = o[key]; // 取出对应属性值
        // newObj[key] = element// 对新对象添加属性和属性值  
        //element 有可能是引用类型 例如gf字段 
        if(element && typeof element =="object") {
          // 如果属性值是对象类型
          newObj[key] = deepCopy(element)
        }  else{
          // 如果属性值是基本类型
          newObj[key] = element
        }
      }
    }
  }
  return newObj
}
var o3 =  deepCopy(obj)
obj.gf.age = 30
console.log(o3)
