深拷贝,浅拷贝和赋值的区别

ECMAScript 的数据类型

在将深拷贝和浅拷贝之前,我们先来重新回顾一下 ECMAScript 中的数据类型。主要分为
基本数据类型(undefined,boolean,number,string,null)
基本数据类型主要是:undefined,boolean,number,string,null。
基本数据类型存放在栈中
存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问。
基本数据类型值不可变

javascript中的原始值(undefined、null、布尔值、数字和字符串)与对象(包括数组和函数)有着根本区别。原始值是不可更改的:任何方法都无法更改(或“突变”)一个原始值。对数字和布尔值来说显然如此 —— 改变数字的值本身就说不通,而对字符串来说就不那么明显了,因为字符串看起来像由字符组成的数组,我们期望可以通过指定索引来假改字符串中的字符。实际上,javascript 是禁止这样做的。字符串中所有的方法看上去返回了一个修改后的字符串,实际上返回的是一个新的字符串值。

基本数据类型的值是不可变的,动态修改了基本数据类型的值,它的原始值也是不会改变的,例如:

var str = "abc";

    console.log(str[1]="f");    // f

    console.log(str);           // abc

这一点其实开始我是比较迷惑的,总是感觉 js 是一个灵活的语言,任何值应该都是可变的,而且之前学c语言的时候有char这个数据类型,这时一个字符数组,是可以更改的,但是js是不一样的,我们通常情况下都是对一个变量重新赋值,而不是改变基本数据类型的值。就如上述引用所说的那样,在 js 中没有方法是可以改变布尔值和数字的。倒是有很多操作字符串的方法,但是这些方法都是返回一个新的字符串,并没有改变其原有的数据

要知道number,string这些其实是没有属性和方法的,但是你又是怎么拿到length等一些数据的呢,是因为有基本包装类型,先new了一下,然后属性方法在执行完后瞬间消失,这也是基本包装类型和引用类型的区别,所以你以为你改了,但是在你改完之后这个数据就已经消失了

所以,记住这一点:基本数据类型值不可变

上 面普及完基本知识之后,下面开始扯我的见解
js这块说破大天,就是引用

赋值:

var a = {
  b: 1,
  c: 2,
  d: {
    e: {
      f: 4
    }
  }
}
var q = a;
console.log(q === a);    // true
console.log(q.b === a.b)    // true
console.log(q.d === a.d)    // true
q.b = 100
q.d.e.f = 200
console.log(a)  // { b: 100, c: 2, d: { e: { f: 200 } } }
console.log(q)  //  { b: 100, c: 2, d: { e: { f: 200 } } }

举个例子:我们把整个数据比作比作一个房子,q和a是父子关系,q现在还比较小,现在还和父亲a一起居住,他们住在同一个房子,房子里面的每一个家具(基本类型数据)都是公有的,家里的墓地(引用类型数据)也是一样的,所以他们无论在家里做什么,无论是动了家具还是去墓地祭拜了,对方所处的环境都会有变化

浅拷贝:

var a = {
  b: 1,
  c: 2,
  d: {
    e: {
      f: 4
    }
  }
}
let r = {}
for (var i in a) {
  r[i] = a[i]
}

console.log(r === a);  //false
console.log(r.b === a.b)  // true
console.log(r.d === a.d)  // true
r.b = 100
r.d.e.f = 200
console.log(a)  // { b: 1, c: 2, d: { e: { f: 200 } } } 
console.log(r)  // { b: 100, c: 2, d: { e: { f: 200 } } }

举个例子:我们把整个数据比作比作一个房子,q和a是父子关系,q现在已经长大了,已经和父亲a分开住了,但是还住在一个城市(访问的同一个墓地),他特别喜欢家里的装修,所以呢他就把新家的家具和父亲a家的搭配的一模一样,所以这两个家的家具也是一样的(基本类型的值是一样的),但是他们都去一个墓地进行祭拜,他们会拿各自的东西,会和对方拿的互相影响(引用类型的值会变)

深拷贝:

var a = {
    b: 1,
    c: 2,
    d: {
      e: {
        f: 4
      }
    }
  }
  var s = _.cloneDeep(a);
  console.log(s === a);  // false
  console.log(s.b === a.b) // true
  console.log(s.d === a.d) // false
  s.b = 100
  s.d.e.f = 200
  console.log(a) 
/**{
	b: 1
	c: 2
	d:{
		e: {
			f: 4
		}
	}
}*/
  console.log(s)
/** {
	b: 100
	c: 2
	d:{
		e: {
			f: 200
		}
	}
}*/

这里无论改基础类型的值还是引用类型的值,都不会影响到对方。
举个例子:我们把整个数据比作比作一个房子,q和a是父子关系,q现在已经非常有钱了,出国了,已经和父亲a分开住了不在同一个城市),他特别喜欢家里的装修,所以他就把新家的家具和父亲a家的搭配的一模一样,所以这两个家的家具也是一样的(基本类型的值是一样的),他也想祭奠先祖,但是又不想回国这可怎么办呢,于是乎,他就在他住的城市也修缮了一个和老家一样的墓地去祭拜先祖,这时当父子同时去祭拜他们的先祖时,是不会遇到的,也不会影响到对方(此时彼此无论修改基本类型的值还是引用类型的值,都不会受到影响)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值