blog icon indicating copy to clipboard operation
blog copied to clipboard

引用类型对象拷贝

Open yongheng2016 opened this issue 7 years ago • 0 comments

1.引用类型有哪些?非引用类型有哪些2.如下代码输出什么?为什么

基本类型:numberbooleanstringnullundefined

引用类型:objectfunctionregexparray

var obj1 = {a:1, b:2}; 
var obj2 = {a:1, b:2};
console.log(obj1 == obj2);   //false   地址不相等
console.log(obj1 = obj2);   //{a:1,b:2}   浅拷贝,obj1拷贝obj2的地址
console.log(obj1 == obj2);   //ture 两个对象相等

3.如下代码输出什么? 为什么

var a = 1
var b = 2
var c = { name: '饥人谷', age: 2 }
var d = [a, b, c]

var aa = a
var bb = b
var cc = c
var dd = d

a = 11
b = 22
c.name = 'hello'
d[2]['age'] = 3

console.log(aa)    //1  基本类型   值的拷贝
console.log(bb)    //2   基本类型   值的拷贝
console.log(cc)   //{name:'hello',age:3}    引用类型   浅拷贝    `c.name`改变了堆中对象的内容,`d[2]['age']=3`改变了堆对象中age的值
console.log(dd)  //[1,2,{name:'hello',age:3}]   数组中的c记录的是地址,浅拷贝,所以里面内容的改变都影响到最终数组的内容  ;

4.如下代码输出什么? 为什么

var a = 1
var c = { name: 'jirengu', age: 2 }

function f1(n){
  ++n
}
function f2(obj){
  ++obj.age
}

f1(a)    
f2(c) 
f1(c.age) 
console.log(a)    //1     f1(a)-->function f1(n){var n=a; ++n}
console.log(c)   //{name:'jirengu',age:3}    同上

5.过滤如下数组,只保留正数,直接在原数组上操作

var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
}
filter(arr)
console.log(arr) // [3,1,2]
var arr = [3,1,0,-1,-3,2,-5];
	function change(arr){
		for (var i=0; i<arr.length; i++){
		if (arr[i]<=0){
			arr.splice(i,1);
			i-=1;
		}
	}
}
change(arr);
console.log(arr);

6.过滤如下数组,只保留正数,原数组不变,生成新数组

var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
}
var arr2 = filter(arr)
console.log(arr2) // [3,1,2]
console.log(arr)  // [3,1,0,-1,-2,2,-5]
function change(arr){
	var arr1=[];
	for (var i=0; i<arr.length; i++){
		if (arr[i]>0){
			arr1.push(arr[i]);
		}
	}
	return arr1;
}

7.写一个深拷贝函数,用两种方式实现

深拷贝思路:

  • jscode
    • 1.分类,每个类型分情况讨论
    • 2.实现递归(能够进行多层嵌套的拷贝)
    • 3.注意死循环,防止栈溢出(a.self = a /自己的子属性指向自己)(如果属性是对象,记录此属性的地址放入数组或对象中,下次遍历如果又出现了这个地址就停止遍历,直接返回)
var a={self: a}
//a对象的属性当中引用了a对象的地址,此时对a进行递归拷贝会无限循环

js的深拷贝(进适用于对象):

 function deepCopy(oldObj) {
        var newObj = {};
        for(var key in oldObj) {
            if(typeof oldObj[key] === 'object') {
                newObj[key] = deepCopy(oldObj[key]);
            }else{
                newObj[key] = oldObj[key];
            }
        }
        return newObj;
    }
  • 借助JSON全局对象的深拷贝: 针对纯 JSON 数据对象的深复制,使用 JSON 全局对象的 parse 和 stringify 方法来实现;但它只能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,即那些能够被 json 直接表示的数据结构。
    • 1.没有引入
    • 2.没有函数(json无法表示函数)

JSON格式深拷贝:

function jsonClone(obj) {
    return JSON.parse(JSON.stringify(obj));
}
var clone = jsonClone({ a:1 });

参考: https://zhuanlan.zhihu.com/p/23251162 http://jerryzou.com/posts/dive-into-deep-clone-in-javascript/

yongheng2016 avatar Jun 08 '17 13:06 yongheng2016