数组拷贝
1、concat
let newArr = [].concat(oldArr)
2、扩展运算符
let newArr = [...oldArr]
3、slice
let newArr = oldArr.slice(0)
4、JSON.parse和JSON.stringify
var newArr = JSON.parse(JSON.stringify(oldArr))
注:上面前三种拷贝方法中concat、扩展运算符、slice只能实现数组的浅拷贝;第四种JSON实现的是数组、对象的深拷贝。
对象拷贝
1、Object.assign
let newObj = Object.assign({},oldObj)
2、扩展运算符
let newObj = {...oldObj}
3、JSON.parse和JSON.stringify
var newObj = JSON.parse(JSON.stringify(oldObj))
注:上面前两种拷贝方法只能实现数组的浅拷贝;第三种JSON实现的是数组、对象的深拷贝。
利用循环和递归实现数组和对象的深拷贝
function clone(obj){
var newObj = null;
if( {}.toString.call(obj)=='[object Object]' ){
newObj = {};
for(var i in obj){
cloneIn(i,newObj,obj);
}
}else if( {}.toString.call(obj)=='[object Array]' ){
newObj = [];
for(var i=0;i<obj.length;i++){
cloneIn(i,newObj,obj);
}
}else{
newObj = obj;
}
function cloneIn(key,newObj,obj){
if( {}.toString.call(obj[key])=='[object Object]' ){
newObj[key] = clone(obj[key])
}else if({}.toString.call(obj[key])=='[object Array]'){
newObj[key] = clone(obj[key])
}else{
newObj[key]=obj[key];
}
}
return newObj;
}
在使用JSON.stringify序列化时,需要注意:
- 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。
- 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。
undefined、
任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成null
(出现在数组中时)。- 所有以 symbol 为属性键的属性都会被完全忽略掉,即便
replacer
参数中强制指定包含了它们。 - 不可枚举的属性会被忽略
JSON.stringify({}); // '{}'
JSON.stringify(true); // 'true'
JSON.stringify("foo"); // '"foo"'
JSON.stringify([1, "false", false]); // '[1,"false",false]'
JSON.stringify({ x: 5 }); // '{"x":5}'
JSON.stringify({x: 5, y: 6});
// "{"x":5,"y":6}"
JSON.stringify([new Number(1), new String("false"), new Boolean(false)]);
// '[1,"false",false]'
JSON.stringify({x: undefined, y: Object, z: Symbol("")});
// '{}'
JSON.stringify([undefined, Object, Symbol("")]);
// '[null,null,null]'
JSON.stringify({[Symbol("foo")]: "foo"});
// '{}'
JSON.stringify({[Symbol.for("foo")]: "foo"}, [Symbol.for("foo")]);
// '{}'
JSON.stringify(
{[Symbol.for("foo")]: "foo"},
function (k, v) {
if (typeof k === "symbol"){
return "a symbol";
}
}
);
// undefined
// 不可枚举的属性默认会被忽略:
JSON.stringify(
Object.create(
null,
{
x: { value: 'x', enumerable: false },
y: { value: 'y', enumerable: true }
}
)
);
// "{"y":"y"}"