Javascript 赋值和引用,浅拷贝和深拷贝

数据和变量之间赋值

就是把纯数据赋给一个变量,可以赋值的类型包含了javascript 的所有类型,即数字,字符,布尔,数组,对象,null,undefined。 所有类型的数据都可以赋给一个变量,但是变量不能赋值给数据,不能反过来

例如 let a = 1; let b = “string”; let c = true; let d = [1,2,3]; let e ={name:’scott’}; let f = null; let g = undefined

变量和变量之间的赋值

就是把一个变量赋值给另外一个变量。这个时候得根据实际数据类型来判断赋值的结果。例如 let b = a,如果a 是数字,字符,布尔,null, undefined ,那么就是实际赋值。 如果 a 是一个数组和对象(包括函数), 那么b就是引用了a 的指针地址

见以下代码

let a = {
  name :'scott',
  height: 170,
  age: 20
}

let b = a;
b.name = 'petter’;
console.log(a);
内存指针存放地址示意图

浅拷贝和深拷贝 – 浅拷贝

如果 a 是一个数组或对象, 那么 let b =a 也是一个浅拷贝,因为b里面放的就是一个指针地址。解析器在解析的时候自动把数组或对象的指针地址放入到变量里面。

见以下代码块

let a = [1,2,3];
let b = [1,2,3];
let c  = a;
if (a == b) {
    console.log('yes')
} else {
    console.log('no')
}
if (a == c) {
   console.log('yes')
} else {
   console.log('no')
}
浅拷贝指针地址示意图

根据上图可以确定,第一个 a == b 这个并不成立,因为在数据是一个数组或者对象的时候解析器无法判断他们是否相等,这个原因可能是因为对象里面可能会在嵌套各种对象(例如日期),数组里面可以有另一个维的数组,所以解析器无法递归到低。 而 a == c 解析器发现两个指针地址都是指向同一个数据,所以是成立的

浅拷贝和深拷贝 – 深拷贝

上面提到数组和对象的浅拷贝,就是说只是把定义好的数据的指针地址赋给另外一个变量。那如果做到把定义好的数据内容完全赋给另外一个变量,这个就叫做深拷贝

let a = {
    name:"scott",
    ff:{
        name:"ffff",
        gg: "gg"
    }
};
let b = JSON.parse(JSON.stringify(a));
console.log(b)

这种做法是直接把对象转化成字符串,再转化为对象,重新赋值给变量,让变量里面存储的不再是指针地址,而是实际的数据。但是这样做有些弊端,如果里面带有日期对象,JSON stringify会把里面的函数,正则表达式等给过滤了,也就是说再次parse之后有些信息会丢失了。如果想做个比较完整的深拷贝,可以写一个递归函数遍历一下对象的所有属性,然后重新赋值即可。

你可能感兴趣的:(Javascript 赋值和引用,浅拷贝和深拷贝)