一、基本数据类型和引用数据类型

基本数据类型:1.Number(数字类型) 2.String(字符串类型) 3. Boolean(布尔类型) 4. Null(空类型) 5.Undefined(未定义类型) 6. Symbol(符号类型)

引用数据类型: Object(对象类型):表示一组无序的键值对,例如 {name: '张三', age: 18}。

基本数据类型是简单的数据类型,它们的值都是直接存储在变量中的,而引用数据类型则是保存在内存中的对象,变量保存的是对象的地址。因此,在比较两个引用数据类型的值时,比较的是它们的引用地址,而非内容。

二、深拷贝和浅拷贝

浅拷贝: 创建一个新对象或数组,新对象或数组的内部元素的引用和原对象或数组相同,即新对象或数组和原对象或数组共享同一块内存地址。当原对象或数组改变时,新对象或数组也会跟着改变。

var a = 10;
var b = a;
a = 100;
console.log(b);  // 10

深拷贝: 创建一个新对象或数组,新对象或数组的内部元素的引用和原对象或数组不同,即新对象或数组和原对象或数组没有共享同一块内存地址。当原对象或数组改变时,新对象或数组不会跟着改变。

var a = [10,20,30];
var b = a;
a[0] = 100;
console.log(b);  // [100,20,30]

三、实现数组和对象深拷贝

1、针对于数组实现深拷贝,可以使用slice和concat方法,还可以使用ES6的展开运算符

 const Arr = ["one", "two", "three"];
 const fxArr = Arr.slice(0);
 fxArr[1] = 'love'
 console.log(Arr); // ["one", "two", "three"]

 const Arr = ["one", "two", "three"];
 const fxArr = Arr.concat(0);
 fxArr[1] = 'love'
 console.log(Arr); //  ["one", "two", "three"]

 const  Arr = ["one", "two", "three"];
 const  fxArr = [...Arr]
 fxArr[1] = 'love'
 console.log(Arr); // ["one", "two", "three"]

2、针对于对象实现拷贝呢,可以使用以下几种方案?

----------------------------使用对象API实现深拷贝-----------------------

 let obj1 = {
       name:"张三",
       age:18
 }
 let obj2 =  JSON.parse(JSON.stringify(obj1));
 obj2.name="李四"
 console.log(obj1);

----------------------------对象一个一个赋值-----------------------

 let obj1 = {
       name:"ruirui",
       age:18
   }
 let obj2 = {}
 obj2.name = obj1.name;
 obj2.age = obj1.age;
 obj2.name = 'shasha'
 console.log(obj1); // {name: "ruirui", age: 18}

-----------------------------ES6扩展运算符---------------------------

let obj1 = {
       name:"ruirui",
       age:18
   }
let obj2 = {...obj1}

--------------------------对象遍历赋值------------------------------

 var p = {
        "id":"007",
        "name":"张三"
 }
 var p2 = {};
 for (let key in p) {
   p2[key] = p[key];
 }
 p2.name = '李四'
 console.log(p); // {id: "007", name: "张三"}

3、上面属于一层,如果含有多层,对象遍历赋值只能外层对象是深拷贝的,内层对象是浅拷贝

 let p = {
        "id":"007",
        "name":"刘德华",
        "books":newArray("三国演义", "红楼梦", "水浒传")//这是引用类型
 }
 function copy(obj){
	   var newobj = {};
	   for(var k in obj){
		   newobj[k] = obj[k]
	   }
	   return newobj
 }

发现实现不了上述要求:下面提供一种递归的思路来进行解决该问题。

 var p = {
        "id":"007",
        "name":"刘德华",
        "wife": {
            "id":"008",
            "name":"刘德的妻子",
            "address": {
                "city":"北京",
                "area":"海淀区"
            }
        }
 }

//编写函数

function copyObj(obj) {
        let newObj = {};
        for (let key in obj) {
            if (typeof obj[key] == 'object') {
             newObj[key] = copyObj(obj[key]); //如:key是wife,引用类型,那就递归**
            } else {
             newObj[key] = obj[key]; //基本类型,直接赋值**
            }
        }
        return newObj;
}
let pNew = copyObj(p);
pNew.wife.name = "张三疯";
pNew.wife.address.city = "香港";
console.log(pNew);
console.log(p);

运行效果 image-20230731164408301.png 需要说明的是,在实际开发中,需要根据具体情况选择适合的拷贝方法。