js对象的深浅拷贝

js对象的深浅拷贝

针对于JavaScript的对象和数组(数组也是对象)浅拷贝只是引用,内存不变;而深拷贝就是递归赋值。
深拷贝是不一样内存,相互独立。而浅拷贝会影响程序员

//1.循环复制数组
var arr = [1,2,3],arr2 = [];
for(var i=0;i<arr.length;i++) {
    arr2[i] = arr[i];
}

//2.还能够用一句简单的代码实现上面的深拷贝:
Array.prototype.push.apply(arr2,arr);

//3.先把这个对象转化为字符串,在拷贝,再转化回来便可
JSON.parse(JSON.stringify(obj))

别急着走,利用window.JSON的方法作深拷贝存在2个 缺点:数组

  • 若是你的对象里有函数,函数没法被拷贝下来
  • 没法拷贝对象原型链上的属性和方法

例以下面这种状况:对象里包含函数数据结构

var o1 = {
    name:"小明",
    age:12,
    city:"广州",
    schools:["小学","中学","大学"],
    say:function(){
            alert(this.name);
    }
}

for...in 遍历对象,找出自身的属性,且会搜索原型,即也会查找原型上的属性
__proto__不可枚举的属性app

obj.hasOwnProperty() 返回布尔值 判断属性是不是自有属性函数

JSON.parse(JSON.stringify(o1)) 能够将只有属性/不存在方法的对象复制
JSON.stringify 将对象转换成字符串,转换的过程,会忽略掉方法.this

//下面的方法能够实现 深深度复制(复制包括函数)spa

function deepClone(oldObj){
        var newObj = {};
        for(var key in oldObj){
                if(oldObj.hasOwnProperty(key)){
                        if(oldObj[key].constructor == Array){ //判断oldObj[key]值是否数组/对象
                                newObj[key] = oldObj[key].slice();
                        }else if(oldObj[key].constructor == Object){
                                newObj[key] == deepClone(oldObj[key]);
                        }else{
                                newObj[key] = oldObj[key];
                        }
                }
        }
        return newObj;
}
var o2 = deepClone(o1);

固然,你明确知道他们的缺点后,若是他的缺点对你的业务需求没有影响,就能够放心使用了,一行原生代码就搞定。
目前我在开发业务场景中,大多还真能够忽略上面2个缺点。每每须要深拷贝的对象里没有函数,也不须要拷贝它原型链上的属性。操作系统


图片描述


js堆栈

因为js中的对象都是复杂数据类型,这种数据在内存中存储的时候,存放在堆中。当简单赋值的时候,实际上是将该对象的指针指向同一个堆地址。
简单的数据类型存放在栈中,当对简单的数据类型进行赋值的时候,其实就是直接在栈中新开辟一个地方专门存储同样的值。prototype

数据结构里的堆栈:
栈(stack): 由编译器自动分配, 存放函数的参数值, 局部变量的值等. 其操做方式相似于数据结构中的栈.
堆(heap): 通常由程序员分配释放, 若程序员不释放, 程序结束时可能由OS回收. 这里OS是指: 操做系统(Operating System)指针

相关文章
相关标签/搜索