zoukankan      html  css  js  c++  java
  • 深入理解对象的引用

    首先我们来讲一下赋值关系和引用关系

    • 赋值关系
    var a = 5;
    var b =a;
    b+ = 3;
    alert(b);//8
    alert(a);//5
    

    a和b是简单的赋值关系,这种赋值关系存在于基本类型中

    • 对于函数和对象,存在的不是简单的赋值关系,而是引用关系

    我们来看两种情况

    var a = [1,2,3]
    var b = a;
    b.push(4);
    alert(a)//1,2,3,4
    alert(b)//1,2,3,4
    

    在这种情况下,a和b共用一个内存空间。就像我们c语言中的指针。用一种更形象的说法:a与b都有一个存库的门,所以他们都能改变这个仓库,都改变的是同一个仓库。

    var a = [1,2,3];
    var b = a;
    b = [1,2,3,4];
    alert(a)//1,2,3
    alert(b)//1,2,3,4
    

    这种情况就和刚才有点不同了。你或许会想,ab不是共用一个内存吗,为什么b变了a不跟着变。
    在这里我们就要注意这两句的区别了

    b.push(4);
    b = [1,2,3,4];
    

    前面一句是用数组方法向仓库里放了一个4,所以ab呈现出来的都是1234毕竟他们用的是一个仓库。而后面一句b = [1,2,3,4];而是创建了一个新数组,重新放入1,2,3,4,这时候他已经和a没有关系了,他放入的前三个数甚至可以不是和a一样的123了。

    我觉得这两个例子就像这样的一个故事:a和b是一对父子,小时候b和爸爸a一起生活,有时为家里添置一点小家具;后来b长大了就自己买房子了,自己可以把房子装修得完全不一样了。(个人理解,帮助记忆而已,不必深究)

    了解了对象的引用关系,下面我们来谈谈怎样复制对象

    对象的拷贝有两种方式,我们称为深拷贝和浅拷贝,浅拷贝就是只复制最表面的那一层对象,我们来看下面这个例子

    var obj = {
    	a:10
    }
    function copy() {//浅拷贝
    	var newObj = {};
    	for(var attr in obj) {
    		newObj[attr] = obj[attr];
    	}
    	return newObj;
    }
    
    var obj2 = copy(obj);
    obj2.a = 20;
    alert(obj.a)//10
    

    在这个例子中,我定义了一个拷贝的函数,这个函数的思路是:把所有a中的属性都复制到b中去,然后返回一个新对象。因为obj对象中只有一层,所以obj2拷贝成功。

    我们再来看看原对象不止一层的情况

    var objX = {
    	a:{b:10}
    }
    var objY = copy(objX);
    objy.a.b = 20;
    alert(objX.a.b)//20 复制失败
    

    这里我们还是使用的上面的拷贝函数。我们可以看到,这一次就拷贝失败了。这就是我说的浅拷贝这能拷贝一层对象。

    下面我们来看深拷贝

    深拷贝其实拷贝的原理和浅拷贝是一样的,我们需要做到的就是把每一层对象都拷贝过去。这里我采用递归的方法。

    递归应该大家都知道,到可能概念模模糊糊,所以我先简单的介绍一下递归。

    • 递归

    递:传递

    归:回到之前的位置

    image.png
    我们来看一个求阶层的例子

    function test(n) {
    	return n*test(n-1);
    }
    

    我们要在它返回的时候再去执行它本身,每次传进的参数会小1.当然,这传递的运算必须要有一个结束的时候,所以我们要进行判断什么时候结束

    function test(n) {
    	if(n==1) {
    		return 1;
    	}
    	return n*test(n-1);
    }
    

    这里在n=1时函数就执行结束了。

    所以总结递归的两个点

    1. 函数调用函数自身,执行递的动作
    2. 最后一次判断一个终止条件,可以执行的动作

    然后我们的深拷贝就开始了

    function deepCopy(obj) {
    	if(typeof obj != 'object') {
    		return obj;
    	}
    	var newObj = {};
    	for(var attr in obj) {
    		newObj[attr] = deepCopy(obj[attr]);
    	}
    	return newObj;
    }
    

    在这里,我们一层一层的往下剥,剥到不是对象的时候就停止了,也就实现了深拷贝

    如果你对我的文章有想说的话,欢迎qq交流:425910502.在这里附上qq主要是因为经常在网上看一些文章,有问题想问作者又得不到作者即使的回复,让人很懊恼,虽然我的文章并不会被很多人看到,但我要对看到我文章的人负责。

  • 相关阅读:
    AtCoder Beginner Contest 205
    Codeforces Round #725 (Div. 3)
    Educational Codeforces Round 110 (Rated for Div. 2)【A
    Codeforces Round #722 (Div. 2)
    AtCoder Beginner Contest 203(Sponsored by Panasonic)
    AISing Programming Contest 2021(AtCoder Beginner Contest 202)
    PTA 520 钻石争霸赛 2021
    Educational Codeforces Round 109 (Rated for Div. 2)【ABCD】
    AtCoder Beginner Contest 200 E
    Educational Codeforces Round 108 (Rated for Div. 2)【ABCD】
  • 原文地址:https://www.cnblogs.com/huyuzhu/p/7840858.html
Copyright © 2011-2022 走看看