实现一个克隆函数,可以深拷贝JS中的5种数据类型

要求: 封装一个克隆函数 clone ,可以对 JavaScript 5 种主要的数据类型(包括 NumberStringObjectArrayBoolean)进行值的深拷贝。(注意:null 、array 和 object 都是属于 Object 类型

    <script>

        // 封装 clone 克隆函数
        function clone(obj) {
            var o;  // 此函数的返回值存储克隆后的数
            switch (typeof obj) {   // 判断条件是 obj 的数据类型
                case 'undefined':   // undefined 类型
                    break
                case 'string':      // 字符串 类型
                    o = obj + ''
                    break
                case 'number':      // 数字 类型
                    o = obj - 0
                    break
                case 'boolean':     // 布尔 类型
                    o = obj
                    break
                case 'object':      // 对象 类型(其中包含三种数据情况)
                    if (obj === null) {     // 值为 null 的情况
                        return o = null
                    } else {
                        // 判断这个对象类型是数组还是一个对象
                        if (Object.prototype.toString.call(obj).slice(8, -1) === 'Array') {
                            o = []
                            // 使用循环嵌套递归一个个将数添加到 o 数组中
                            for (let i = 0; i < obj.length; i++) {
                                o.push(clone(obj[i]))
                            }
                        } else {
                            o = {}
                            // 使用 for...in 遍历对象嵌套递归将对象属性和值对应并赋值给 o 对象
                            for (const k in obj) {
                                o[k] = clone(obj[k])
                            }
                        }
                    }
                    break
                // 若类型不属于上述所有情况则直接为 o 赋值
                default:
                    o = obj
                    break

            }
            // 将 o 作为返回值 return 给调用者
            return o;
        }
        // var a = []  // [object Array]
        // let str = Object.prototype.toString.call(a)
        // console.log(str.slice(8, -1));  // Array

        var obj = { id: 1, name: 'zs', age: 13 }

        console.log('该数的原始类型是:' + typeof obj);  // 该数的原始类型是:object
        var str = clone(obj);     // 调用克隆函数将返回值赋值给 str
        obj.name = 'li'     // 这里修改了 obj 中的属性值不会影响 str 所以是深拷贝
        console.log('obj = ', obj);  // obj =  {id: 1, name: 'li', age: 13}
        console.log('str = ', str);  // str =  {id: 1, name: 'zs', age: 13}

    </script>

解析:在判断对象是属于 Array 还是 Object 时我们可以直接使用 Object.prototype.toString 方法,但是我们还需要使用 call() 方法来改变 this 指向到我们的对象上,比如:

var a = []
var b = {}
console.log(Object.prototype.toString.call(a)); // [object Array]
console.log(Object.prototype.toString.call(b)); // [object Object]

然后我们再使用 slice(start , stop) 方法来截取字符串,该方法用于通过开始点和结束点来限制组合中元素的选择:start 参数是创建子集的开始索引(从 0 开始),stop 参数是一个可选的结束点(截取到的内部不包含 stop 所在的点)。

var a = []
console.log(Object.prototype.toString.call(a).slice(8, -1)); // Array

如此,我们最后根据一个对象的 Object.prototype.toString.call(obj).slice(8, -1) 等于 Array 还是 Object 即可判断出该对象是数组类型还是对象类型

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值