深复制
JSON.stringify() 有缺点
var obj = {
a: 'a',
b: undefined,
c: /\d+/,
d: [1, null, () => false, undefined],
e: Symbol('e'),
f: this.b,
};
JSON.stringify(obj);
/**
{
"a": "a",
"c": {},
"d": [1, null, null, null]
}
*/
JSON.stringify()将值转换为相应的JSON格式:
- 转换值如果有 toJSON() 方法,该方法定义什么值将被序列化。
- 非数组对象的属性(即值不为 [] 的属性,有可能属性会被忽略) 不能保证以特定的顺序出现在序列化后的字符串中。
- 布尔值、数字、字符串 的包装对象在序列化过程中会自动转换成对应的原始值。
- undefined 、任意的 函数 以及 symbol 值,在序列化过程中会 被忽略 (出现在 非数组对象的属性值 中时)或者 被转换成 null (出现在 数组 中时)。函数、undefined、Symbol 被 单独转换 时,会返回 undefined ,如JSON.stringify(function(){}) or JSON.stringify(undefined) or JSON.stringify(Symbol('a')).
- 对包含 循环引用 的对象(对象之间相互引用,形成无限循环)执行此方法,会 抛出错误 TypeError ("cyclic object value") 。
- 所有以 symbol 为属性键 的属性都会被完全 忽略 掉,即便 replacer 参数中强制指定包含了它们。
- Date 日期调用了 toJSON() 将其转换为了 string 字符串(同Date.toISOString()),因此会被当做 字符串 处理。
- NaN 和 Infinity 格式的数值及 null 都会被当做 null 。
- 其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性。
- 对 正则对象 RegExp 转成了 空对象 {}
如何写出一个惊艳面试官的深拷贝