(知识点)化学实验基本内存的实现方式与图解

  目录一.数据类型二.浅拷贝与深拷贝三.赋值和浅拷贝的区别四.浅拷贝的实现方式五.深拷贝的实现方式一.数据类型

  数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型。

  基本数据类型:

  访问:基本数据类型的值是按值访问的。

  存储:基本类型的变量是存放在栈内存(Stack)里的。

  图解 : 栈内存中包括了变量的标示符和变量的值。

  引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里

  引用数据类型在栈中储存了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获取实体。

  访问:引用类型的值是按引用访问的。

  存储:引用类型的值是保存在堆内存(Heap)中的对象(Object)。

  图解:

  栈内存中包含了变量的标示符和指向堆内存中该对象的指针

  堆内存中包含了对象的内容

  image

  JavaScript 不能直接操作对象的内存空间(堆内存)一.浅拷贝与深拷贝

  深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。

  深拷贝和浅拷贝的示意图大致如下:

  image

  浅拷贝只复制指向某个对象的指针,而不是复制对象本身 新旧对象还是共享同一块内存。

  但深拷贝会另外创造一个一摸一样的对象, 新对象跟原对象不共享内存,修改新对象不会改到原对象。三.赋值和浅拷贝的区别

   // 对象赋值

  1. var obj1 = {
  2. 'name' : 'zhangsan',
  3. 'age' : '18',
  4. 'language' : [1,[2,3],[4,5]],
  5. };
  6. var obj2 = obj1;
  7. obj2.name = "lisi";
  8. obj2.language[1] = ["二","三"];
  9. console.log('obj1',obj1)
  10. console.log('obj2',obj2)

  image

   // 浅拷贝

  1. var obj1 = {
  2. 'name' : 'zhangsan',
  3. 'age' : '18',
  4. 'language' : [1,[2,3],[4,5]],
  5. };
  6. var obj3 = shallowCopy(obj1);
  7. obj3.name = "lisi";
  8. obj3.language[1] = ["二","三"];
  9. function shallowCopy(src) {
  10. var dst = {};
  11. for (var prop in src) {
  12. if (src.hasOwnProperty(prop)) {
  13. dst[prop] = src[prop];
  14. }
  15. }
  16. return dst;
  17. }
  18. console.log('obj1',obj1)
  19. console.log('obj3',obj3)

  image

  上面例子中,obj1是原始数据,obj2是赋值操作得到,而obj3浅拷贝得到。我们可以很清晰看到对原始数据的影响,具体请看下表:

  image

  四.浅拷贝的实现方式

  1.Object.assign()

  Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象js array slice 浅拷贝,然后返回目标对象。但是 Object.assign()进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

  js深拷贝和浅拷贝_js array slice 浅拷贝_js深拷贝和浅拷贝的区别

   var obj = { a: {a: "xxxc", b: 19} };

  1. var initalObj = Object.assign({}, obj);
  2. initalObj.a.a = "wewd";
  3. console.log(obj.a.a); //wewd

  注意:当object只有一层的时候js array slice 浅拷贝,是深拷贝

   let obj = {

  1. username: 'jsx'
  2. };
  3. let obj2 = Object.assign({},obj);
  4. obj2.username = 'wawa';
  5. console.log(obj);//{username: "jsx"}

  2.Array.prototype.concat()

   let arr = [1, 3, {

  1. username: 'kobe'
  2. }];
  3. let arr2=arr.concat();
  4. arr2[2].username = 'wade';
  5. console.log(arr);

  修改新对象会改到原对象:

  example

  3.Array.prototype.slice()

   let arr = [1, 3, {

  1. username: ' kobe'
  2. }];
  3. let arr3 = arr.slice();
  4. arr3[2].username = 'wade'
  5. console.log(arr);

  修改新对象会改到原对象:

  image

  Array的slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。

  原数组的元素会按照下述规则拷贝:

   let arr = [1, 3, {

  1. username: ' kobe'
  2. }];
  3. let arr3 = arr.slice();
  4. arr3[1] = 2
  5. console.log(arr,arr3);

  image

  五.深拷贝的实现方式

  1.递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝

   var deepCopy = function(obj) {

  1. if (typeof obj !== 'object') return obj //判断不是object就直接返回
  2. var newObj = (Object.prototype.toString.call(obj) === '[object Array]') ? [] : {} //判断复制的目标是数组还是对象
  3. for (var key in obj) {
  4. if (obj.hasOwnProperty(key)) {
  5. newObj[key] = (typeof obj[key] !== 'object') ? obj[key]: deepCopy(obj[key]) // 如果值是对象,就递归一下。 如果不是,就直接赋值
  6. }
  7. }
  8. return newObj
  9. }

  就这么简单。

  js深拷贝和浅拷贝_js深拷贝和浅拷贝的区别_js array slice 浅拷贝

  类似的方法都是挺雷同的

   function deepClone(source){

  1. const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
  2. for(let keys in source){ // 遍历目标
  3. if(source.hasOwnProperty(keys)){
  4. if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
  5. targetObj[keys] = source[keys].constructor === Array ? [] : {};
  6. targetObj[keys] = deepClone(source[keys]);
  7. }else{ // 如果不是,就直接赋值
  8. targetObj[keys] = source[keys];
  9. }
  10. }
  11. }
  12. return targetObj;
  13. }
  14. /*原理都一样*/
  15. var deepClone=function(source) {
  16. if (!source && typeof source !== 'object') {
  17. throw new Error('error arguments', 'deepClone')
  18. }
  19. const targetObj = source.constructor === Array ? [] : {}
  20. Object.keys(source).forEach(keys => {
  21. if (source[keys] && typeof source[keys] === 'object') {
  22. targetObj[keys] = deepClone(source[keys])
  23. } else {
  24. targetObj[keys] = source[keys]
  25. }
  26. })
  27. return targetObj
  28. }

  2.除此之外还有 函数库 lodash

  该函数库也有提供_.cloneDeep用来做 Deep Copy

   var _ = require('lodash');

  1. var obj1 = {
  2. a: 1,
  3. b: { f: { g: 1 } },
  4. c: [1, 2, 3]
  5. };
  6. var obj2 = _.cloneDeep(obj1);
  7. console.log(obj1.b.f === obj2.b.f);
  8. // false

  JSON.parse(JSON.stringfify(obj))

  3.JSON.parse(JSON.stringfify(obj))

  原理:

  用JSON.stringify将对象转成JSON字符串,

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

  可以实现数组或对象深拷贝,但不能处理函数

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

  可以自行试验 就不做图例了,太懒了

文章由官网发布,如若转载,请注明出处:https://www.veimoz.com/1477
0 评论
724

发表评论

!