实现一个克隆函数,可以深拷贝JS中的5种数据类型
程序员文章站
2022-06-09 19:09:49
...
要求: 封装一个克隆函数 clone ,可以对 JavaScript 中 5 种主要的数据类型(包括 Number、String、Object、Array、Boolean)进行值的深拷贝。(注意: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 即可判断出该对象是数组类型还是对象类型。
上一篇: C#读取txt文件数据的方法实例
下一篇: RecyclerView实现横向滚动效果