手写深拷贝>/遍历对象的方法

深拷贝写法>遍历对象的方法

手写深拷贝如下:

function deepCopy(obj) {
    
    
    //判断是否是简单数据类型,
    if (typeof obj == "object") {
    
    
        //复杂数据类型
        var result = obj.constructor == Array ? [] : {
    
    };
        //对于数组和对象,result的类型不一样,不过调用方式一样,都是result[i]
        for (let i in obj) {
    
    
            // console.log(i);
            result[i] = typeof obj[i] == 'object' ? deepCopy(obj[i]) : obj[i];
        }
    } else {
    
    
        //简单数据类型 直接 == 赋值
        var result = obj;
    }
    return result;
}

深拷贝原理很简单, 就是多层"浅拷贝", 直到碰到普通数据类型直接赋值.

小tip: 判断数组可以用继承自原型对象的constructor属性,它指向构造函数

obj.constructor == Array ? [] : {
     
     };

还有其他方法: 本质也是利用原型链来判断

obj instanceof Array ? [] : {
     
     };
Array.isArray(obj) ? [] : {
     
     };

但是我仍然碰到很多小bug, 所以要复习以下字符串的基础知识;

1.字符串的属性类型: 都行

var obj2 = {
    name: 'peiqi', //属性名是标识符
    age: '4',
    brother: {
        name: 'jorge',
        age: 2,
    },
    family: ['fa', 'ma'], //属性名是数组名
    '字符串': 123, //属性名是字符串
    null: 123, //null被当成标识符了,避免歧义不要这样
    undefined: 123,
};

2.用for item in obj 遍历字符串时, item是string格式, 自带"隐形的"引号

for (var i in obj2) {
    var tt = typeof i;
    console.log(tt + i);
}

在这里插入图片描述

就算是数组也是一样的,字符串形式的下标:

var arr1 = [{
    
    
    soft: 18
}, {
    
    
    road: 23
}, 123, '123']

for (var i in arr1) {
    
    
    console.log(i);
    console.log(typeof i);
}

在这里插入图片描述

3.获取属性方法

之前说过两种方法:

obj.p // "Hello World"	//打点的形式不能打引号
obj['p'] // "Hello World"	//如果用中括号需要打引号,否则定位不到obj.p这个指针

进行细节补充:

       obj2[name] = 'road'; //中括号不打引号定位不到obj2.name;
        console.log('1次' + obj2.name); //1次peiqi, 说明对象的name属性并未改变
        obj2['name'] = 'key';
        console.log('3次' + obj2.name);


        console.log(obj2['字符串']); //成功输出123
        console.log(obj2["'字符串'"]); //undefined, 即使是字符串也不用打两次引号!,一次引号即可

总结: 不过属性名是什么类型, 不要在打点形式里带引号, 也不要在中括号形式里不打引号, 或者打两个引号

总结2,3, 所以在for in遍历方式里, 要注意用obj[item]格式, 不要打引号, 因为item本身就是string格式, 自带引号; 也不要用obj.item格式

在这里插入图片描述

おすすめ

転載: blog.csdn.net/Fky_mie/article/details/116132885