深拷贝+浅拷贝+数据类型判断

深拷贝浅拷贝的原理

  • 浅拷贝

  • 浅拷贝就是对数据的复制
  • 浅拷贝的使用方法

	// 浅拷贝的方法
	let arr = [1,2,3,4];
	let newArr = arr;
  • 浅拷贝的缺点
    当你创建一个新的变量newArr直接复制已有变量的数据时,你改变原变量arr数据,新的变量newArr数据也会发生改变,最终两个的变量值是一样的
   // 浅拷贝的方法
   let arr = [1,2,3,4];
   let newArr = arr;
   arr[0] = 999;
   console.log(arr,newArr) // 结果[1,2,3,999] [1,2,3,999];
  • 深拷贝

    • 深拷贝生成一个新的存储空间,将数据复制到这个新的存储空间中,从而改变原数据不会影响深拷贝后的数据
  • 深拷贝的使用方法

  • 扩展运算符
  • 扩展运算就是,生成一个新的数据类型,相当于开辟一个新的指针,将原数据通过扩展运算符进行赋值
	let arr = [1,2,3,4];
	let newArr = [...arr];
	arr[0] = 999;
	// 改变原数据的值,不会影响深拷贝后的数据
	console.log(arr,newArr) // 结果[1,2,3,999] [1,2,3,4];
  • 缺点:不会改变深层次数据的指针,深层次数据的指针还是指向原数据,否则改变原数据的深层次深拷贝后的数据的深层次也会发生改变
	let arr = [1,2,3,4,{name:'李四'}];
	let newArr = [...arr];
	arr[arr.length - 1].name = '张三';
	console.log(arr,newArr) // 结果[1,2,3,4,{name:'张三'}],[1,2,3,4,{name:'张三'}]
  • json转换的方法
    • son转换将数据转换成字符串,在转换为原数据类型,复制给新变量
	let arr = [1,2,3,4,{name:'李四'}];
	let newArr = json.parse(json.stringify(arr))
	arr[arr.length - 1].name = '张三';
	console.log(arr,newArr) // 结果[1,2,3,4,{name:'张三'}],[1,2,3,4,{name:'李四'}]
  • Object.assign()方法
  • 他有两个参数,第一个是要合并的类型,第二个是合并的目标,改变原数据不会影响深拷贝后的数据
	let arr = [1,2,3,4,{name:'李四'}];
	let newArr = Object.assign([],arr)
	arr[0] = 999
    console.log(arr,newArr);
  • 缺点:不会改变深层次数据的指针,深层次数据的指针还是指向原数据,否则改变原数据的深层次深拷贝后的数据的深层次也会发生改变
	let arr = [1,2,3,4,{name:'李四'}];
	let newArr = Object.assign([],arr)
	arr[arr.length - 1].name = '张三';
	console.log(arr,newArr) // 结果[1,2,3,4,{name:'张三'}],[1,2,3,4,{name:'张三'}]
  • 递归方法
	var obj = { // 定义要进行深复制的对象
            name: "张三",
            age: 14,
            tel: 110,
            info: {
                isSingle: true
            }
        }
		// 定义深复制的函数
        function deepClone(params) {
        	// 创建一个接受递归后数据的变量
            var obj = {}
            // 如果形参的数据不是Object的话return
            if(!(params instanceof Object)) return
            // 循环形参的数据
            for(let key in params) {
            	// 判断循环出的数据是否为Object
                if(params[key] instanceof Object) {
                	// 如果是Object拿之前的创建的变量接收一个函数的自我调用,将Object以实参传递给当前函数
                    obj[key] = deepClone(params[key])
               // 循环出的数据不为Object
                } else {
                	// 将数据直接赋值给生成的变量
                    obj[key] = params[key]
                }
            }
            // 将接收的数据return出去
            return obj
        }
		// 验证结论
        var obj2 = deepClone(obj)
        obj2.name = '李四'
        obj2.info.isSingle = false
        console.log(obj, obj2)

原型

  • 以图参考

数据类型

  • 数据类型两种

基本数据类型:number、string、boolean、undefined、null,es6新增symbol , 值存在栈中
引用数据类型:Object、Array、function,值存在堆中

  • 判断数据类型的四种方法
  • typeOf:主要判断基本数据类型
	let arr = 1;
	console.log(typeOf(arr)) // 结果Number
	let arr2 = 'abc';
	console.log(typeOf(arr2)) // 结果String
  • 缺点:当数据为引用数据类型时,判断出结果就是字符串object
	let arr = [1,231,4];
	console.log(typeOf(arr)) // 结果object
  • instanceOf:主要用于判断引用数据类型
	let arr = [1,231,4];
	console.log(arr instanceof Array); // 结果为true
  • 缺点:当数据为基本数据类型时,判断出结果就是false
		let num = 1;
        let num2 = '1';
        console.log(num instanceof Number); // 结果为false
        console.log(num2 instanceof String); // 结果为false
  • constructor:对引用数据类型和基本数据类型都有很好的判断,但是如果生成一个函数,把他的原型指向数组后者对象,那么他的判断结果就不一定是函数了
  • Object.prototype.toString.call():完美判断所有数据的类型,如果需要判断深层数据时,需要使用递归的方式
	let arr = [1,2,3,4,{name:'李四'}];
	let num = 1;
	let str = '1';
	let obj = {name:'张三'};
    console.log(Object.prototype.toString.call(arr)); // 结果为 [object Array]
    console.log(Object.prototype.toString.call(num)); // 结果为 [object Number]
    console.log(Object.prototype.toString.call(str)); // 结果为 [object String]
    console.log(Object.prototype.toString.call(obj)); // 结果为 [object Object]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值