深入分析Js变量存储及浅拷贝深拷贝问题

一、数据类型
  1. 值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
  2. 引用数据类型:对象(Object)、数组(Array)、函数(Function)。
二、存储方式及复制、拷贝

首先内存中分为两块区域一块叫栈,一块叫堆。

  1. 基础数据类型保存在栈内存中。例如
var a = 1
var b = a

这里’1’是数值类型,这时会在栈上开辟一个空间 用来去存储它,那a就是用来调用他的名字。b = a,这时,又会在栈上开辟一个空间,这里面存着跟a一样的值’1’,但它的名字为b,所以到这时内存中现在有两个空间,分别存储着数值’1’,一个是空间为a,一个是空间为b,如果这时b = 2,会在先找到b的空间,把1替换成2,那其实对a是没有任何影响的,

a=1
b=1

但是当数据类型为字符串数据类型时就又有变化了,例如

var str = 'abc'
var str2 = str

这段代码和数值类型一样,先在栈上开辟空间,存对应的字符串。

str = ‘abc’
str2 = ‘abc’

但是当改变str2的值的时候str2 = 'abcd',不会到str2的空间直接把’abc’替换为’abcd’,而是开辟新的空间去存储新的值,然后把变量名指向新的空间,旧的空间由于没有名字调用了会被删除回收。这也是字符串的不可改变性
undefined 和 null 就是在栈上开辟空间存上undefined 和 null

  1. 引用数据类型的指针(对象的地址)保存在栈内存中,数据保存在堆内存中。
var obj = {
    name:'zs'
    age: 18
}
obj_address(对象地址)name:‘zs’ ,age: 18

对象的复制,以及浅拷贝的区别,简单的复制只是引用的拷贝。浅拷贝是拷贝一层,更深层次对象级别的也只拷贝引用。浅拷贝可以通过Object.assign(target, ...sources)或对象遍历实现。

   var obj1 = {
            name: 'zs'
        }
        var obj2 = obj1 
        //这时只是将obj1的的地址赋值给obj2,地址还是指向同一个对象,所以
        //当后面执行obj2.name = '123'的时候,obj1.name也为123

        var obj3 = {}
        for (k in obj1) {
            obj3[k] = obj1[k]
        }
        //浅拷贝的一种方式,当前拷贝了一层所以obj3.name的值为zs而不是123
        console.log(obj1.name, obj2.name, obj3.name);//zs zs zs
        obj2.name = '123'
        console.log(obj1.name, obj2.name, obj3.name);//123 123 zs

而深拷贝则是拷贝多层,对每一级别的数据都会进行拷贝。可以理解为在堆内存中开辟了新的空间,将要拷贝的对象完完全全的复制了一份新的数据放入其中,然后在栈内存中有一个新的引用指向它。此时,修改它的内容将不会影响拷贝的父本。深拷贝可以通过json转换的方式实现,例如

var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));

或者递归

function deepClone(initalObj, finalObj) {    
  var obj = finalObj || {};    
  for (var i in initalObj) {        
    var prop = initalObj[i];  // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
    if(prop === obj) {            
      continue;
    }        
    if (typeof prop === 'object') {
      obj[i] = (prop.constructor === Array) ? [] : {};            
      arguments.callee(prop, obj[i]);
    } else {
      obj[i] = prop;
    }
  }    
  return obj;
}
var str = {};
var obj = { a: {a: "hello", b: 21} };
deepClone(obj, str);
console.log(str.a);

以及lodash函数库实现深拷贝。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值