Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

深拷贝 #57

Open
imfenghuang opened this issue Jul 30, 2024 · 0 comments
Open

深拷贝 #57

imfenghuang opened this issue Jul 30, 2024 · 0 comments

Comments

@imfenghuang
Copy link
Owner

imfenghuang commented Jul 30, 2024

1. JSON.parse(JSON.stringify())

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

  1. 非数组对象的属性顺序不能保证以特定的顺序出现在序列化后的字符串中;
  2. 布尔值、数字、字符串的包装对象在序列化的过程中,会自动转化成对应的原始值;
  3. undefined任意 functionsymbol 值,在序列化的过程中,呈现以下两种情况:
    3.1 数组中,转化成 null
    3.2 非数组中(对象属性值时),忽略
// 3.1
const obj = [undefined, ()=>{}, Symbol(foo)]
const cloneObj = JSON.parse(JSON.stringify(obj))
// [null, null, null]

// 3.2
const obj = {
  a: undefined,
  b: () => {},
  c: Symbol('foo')
}
const cloneObj = JSON.parse(JSON.stringify(obj))
// {}
  1. 任意 functionundefined 被单独转化时,会返回 undefined,但是 JSON.parse(undefined) 会抛错 SyntaxError: "undefined" is not valid JSON
JSON.stringify(function(){})
// undefined

JSON.stringify(undefined)
// undefined
  1. 包含循环引用的对象,会抛错;
  2. 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们;
  3. Date 日期调用了 toJSON() 将其转换为了 string 字符串(同 Date.toISOString()),因此会被当做字符串处理;
  4. NaNInfinity 格式的数值及 null 都会被当做 null
JSON.stringify(NaN)
// 'null'

JSON.stringify(Infinity)
// 'null'

JSON.stringify(null)
// 'null'
  1. 其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性;

2. structuredClone

https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Structured_clone_algorithm

  1. 原型链会被丢弃;
  2. function 不能被结构化克隆;
  3. 属性描述符,setters 以及 getters(以及其他类似元数据的功能)同样不会被复制。例如,如果一个对象用属性描述符标记为 read-only,它将会被复制为 read-write,因为这是默认的情况下
  4. RegExp 对象的 lastIndex 字段不会被保留
const function Person() {} 
Person.prototype.a = 1
Person.prototype.foo = ()=>{}

const p = new Person()
const a = {p: p}
// {p: Person}

const cloneA = structuredClone(a)
// {p:{}}

image

2.1 结构化克隆支持的类型

JavaScript 类型

  • Array
  • ArrayBuffer
  • Boolean
  • DataView
  • Date
  • Error 类型(仅限部分 Error 类型)。
  • Map
  • Object 对象:仅限简单对象(如使用对象字面量创建的)。
  • 除 symbol 以外的基本类型。
  • RegExp:lastIndex 字段不会被保留。
  • Set
  • String
  • TypedArray

Error 类型

仅支持以下 Error 类型:Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError(或其他会被设置为 Error 的)

3. 自定义深拷贝

4. 其他外部库

lodash/deepClone

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant