发表于: 2020-02-25 21:50:03

0 1776


今天完成的事情:


对今天查阅的资料理解整合之后,记录如下:


深拷贝和浅拷贝针对的是引用类型。基本类型的名值存储在栈中,当复制时,栈内存会开辟一个栈内存。所以二者修改时,彼此不会影响。

浅拷贝复制的是指向对象的指针,并没有开辟新的栈内存,原对象和新对象还是共享同一块内存,修改新对象自然会影响原对象。

深拷贝会开辟新的栈内存,原对象和新对象不共享同一块内存,修改新对象不会影响到原对象。


  简单来说,浅拷贝只复制一层对象的属性,而深拷贝复制则递归复制了所有层级。



//

浅拷贝只复制一层对象的属性,并不包括对象里面为引用类型的数据。

浅拷贝就是拷贝了一层,除了对象是拷贝的引用类型,其他都是直接将值传递,有自己的内存空间

深拷贝:将 B 对象拷贝到 A 对象中,包括 B 里面的子对象,
浅拷贝:将 B 对象拷贝到 A 对象中,但不包括 B 里面的子对象

//



  如果是基本数据类型,名字和值都会储存在栈内存中,如果是引用数据类型,名字存在栈内存中,值存在堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值


   基本数据类型存放在栈中:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问。

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

  在我们进行赋值操作的时候,基本数据类型的赋值(=)是在内存中新开辟一段栈内存,然后再把再将值赋值到新的栈中

所以说,基本类型的赋值的两个变量是两个独立相互不影响的变量。


//


把一个对象赋值给另一个变量时,并没有创建一个新对象,而是把原对象在栈中的地址(而非栈中的数据)赋给了新对象,即赋的是原对象在栈中的地址,原对象和新对象指向的是同一个地址。因此,两个对象的联动的,修改其中一个,另一个也会改变。包括里面所有的属性,不论是基本类型的数据,还是对象引用。


//


var arr=1;
var arr1=arr;
arr1=5;
console.log(arr,arr1// 1,5 




  引用数据类型值可变

  引用类型的赋值是传址只是改变指针的指向,例如,也就是说引用类型的赋值是对象保存在栈中的地址的赋值,这样的话两个变量就指向同一个对象,因此两者之间操作互相有影响

var arr=[1,2,3]
var arr1=arr;
arr1[0]=5;
console.log(arr,arr1




Object.assign()就是浅拷贝。但是它又有一点特殊的地方,就是可以处理第一层的深拷贝。

var obj1 = { a: 1b: { c: 2 } };
var obj2 = Object.assign({}, obj1);
obj2.a = 3;
obj2.b.c = 3;
console.log(obj1); 
console.log(obj2); 






//


Object.assign()只会拷贝所有的属性值到新的对象中,如果属性值是基本类型,则修改其中一个对象,不会影响另一个。而如果属性值是对象的话,拷贝的是对象的引用,而不是对象本身。所以该方法是浅拷贝。 Object.assign第一个参数必须是个空对象

属性值是基本类型,修改其中一个对象,不会影响另一个对象的该属性:

var ko = {
    name: "peter",
 };
 var newObj = Object.assign({}, ko);
 newObj.name = "lily";
 console.log(ko.name//peter


属性值是引用类型,由于拷贝的是对象的引用,共享相同的地址:

var ko = {
    info: {
        name: "peter",
        age: 8
    }
};
var newObj = Object.assign({}, ko);
newObj.info.name = "lily";
console.log(ko.info.name); //lily



解构赋值

 var obj1 = {a: 1b: 2}
 var obj2 = {...obj1}
 obj2.a = 4
 console.log(obj1obj2)


这两种拷贝有一个问题就是只能赋值一层

//



Arr.concat()方法用于合并两个或多个数组

Arr.slice()方法返回一个新的数组对象 这一对象是一个由 begin和 end(不包括end)决定的原数组的浅拷贝。原始数组不会被改变。

修改新数组的对象会影响到原数组,修改新数组的基本类型值不会影响到原数组




深拷贝


 这种方法它会抛弃对象的constructor。深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object

这种方法能正确处理的对象只有 Number, String, Boolean, Array,即那些能够被JSON直接表示的数据结构。

var obj1 = { a: { b: 1 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj2)


用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象。一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。

这种方法虽然可以实现数组或对象的深拷贝,但不能处理undefine、function、symbol

因为JSON.stringify() 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串,不能接受undefine、function、symbol

var iniArr = {a: {b: 'old'}, c:undefinedd: function () {}, e:  Symbol('')}
var newArr = JSON.parse(JSON.stringify(iniArr));
console.log(iniArr,newArr);

jQuery的$.extend()

var newObj = $.extend(true, {}, iniObj);






_________________________________________________________________________________________


   instanceOf

    用于实例和构造函数的对应。

    typeof []的结果是object,无法判断除数组类型,但是可用instanceOf来判断:

[] instanceof Array //true


hasOwnProperty() 方法会返回一个布尔值,这个方法可以用来检测一个对象是否含有特定的自身(非继承)属性。




明天计划的事情:


总结任务四深度思考,学习es6



遇到的问题:




收获:


深浅拷贝



返回列表 返回列表
评论

    分享到