JS 封装一个方法,对五种主要数据类型(String Boolean Number Undefined Null)进行值复制(深度克隆)
方法一
Object.prototype.clone = function(){
//this指向 a
var o = this.constructor === Array ? [] : {}; //判断传进来的是数据是否是数组,是则创建一个新数组,不是则创建一个对象
for(var e in this){
o[e] = typeof this[e] === "object" ? this[e].clone():this[e]; //判断e是否是普通变量,不是则继续递归遍历
}
return o;
}
var a = [1,2,3];
// var a = {name:"张三"}
var b= a.clone();
b.push(1);
console.log(a); //[1,2,3]
console.log(b); //[1,2,3,1]
方法二:
function clone(Obj){
var buf;
if(Obj instanceof Array){
buf = [];//创建一个空数组
var i = Obj.length;
while(i--){
buf[i] = clone(Obj[i]);
}
return buf;
}else if(Obj instanceof Object){
buf = {};//创建一个空对象
for(var k in Obj){//为这个新对象添加新属性
buf[k] = clone(Obj[k]);
}
return buf;
}else{ //普通变量直接赋值
return Obj;
}
}
var a = [1,2,3];
var b= clone(a);
b.push(1);
console.log(a);//[1,2,3]
console.log(b);//[1,2,3,1]
方法三:
function deepClone (argument) {
var result;
var argumentType = isClass(argument);
if(argumentType === "Object"){
result = {};
}else if(argumentType === 'Array'){
result = [];
}else{
return argument;
}
for(var key in argument){
var copy = argument[key];
if(isClass(copy) === 'Object' || isClass(copy) === 'Array'){
result[key] = arguments.callee(copy); //用callee方法返回当前执行函数进行递归处理 保证deepClone()方法赋值给别的变量该方法正常可以运行
//这里说明一下 caller是返回一个队函数的引用,该函数调用了当前函数,如函数f调用了deepClone函数,则caller指向的是函数a
//callee是返回正在被执行的function函数,也就是所指定的function对象的正文,这里指的是deepClone
}else{
result[key] = argument[key];
}
}
return result;
}
function isClass(o){
return Object.prototype.toString.call(o).slice(8,-1); //call实现继承 如形式[object Array] 截取"Array"字符串
}
var a = [1,2,3];
var b= deepClone(a);
b.push(1);
console.log(a);//[1,2,3]
console.log(b);//[1,2,3,1]
方法四:
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE
但是该方法也是有局限性的:
- 会忽略 undefined
- 会忽略 symbol
- 不能序列化函数
- 不能解决循环引用的对象
网友评论