prefacio
Cuando se trata de una copia profunda de JS, dos métodos de implementación pueden aparecer automáticamente en su mente:
-
JSON.parse(JSON.stringify(obj))
-
clon de lodash profundo
Los dos métodos de copia profunda anteriores tienen algunas desventajas (que se describirán en detalle más adelante en este artículo), por lo que al aprender los métodos de copia profunda anteriores, es posible que haya pensado por qué el navegador no es compatible con la copia profunda nativa. Esto no está estructurado Clonar aquí ~ La API de copia profunda admitida de forma nativa por el tiempo de ejecución del navegador
Desventajas de JSON.parse(JSON.stringify(obj))
-
Si su objeto obj tiene una referencia circular, este método informará un error
-
Si su objeto obj tiene un objeto Fecha, este método lo convertirá en una cadena
-
Si hay objetos Set, Map, Regular, Error en su objeto obj, este método los convertirá en objetos literales vacíos { }, si no está definido, este método ignorará directamente
Vea los resultados de la ejecución en la figura anterior, los objetos Set, Map, Regular y Error se han convertido en { } y undefined ha desaparecido. . .
Posibles riesgos de Lodash
El movimiento de árboles de Lodash puede ser diferente de nuestro pensamiento. Si el andamiaje de su proyecto no maneja este problema y no presta atención a la forma en que se presenta, causará una pérdida de rendimiento.
Para hacer frente a la sacudida de árboles de lodash, consulte:
Importar lodash bajo demanda - One Leaf One Bodhi 22 - 博客园
Hay ciertos problemas en los dos métodos comunes de copia en profundidad* (pero también tienen sus propias ventajas. Los lectores deben elegir el método de copia en profundidad adecuado en función de su propia comprensión de la copia en profundidad y el uso de la escena. Este artículo comparará brevemente el tres métodos de copia en profundidad al final. method)*, lo que lleva astructuredClone, el protagonista de este artículo:
Introducción a la sintaxis de los clones estructurados
全局的 structuredClone() 方法使用结构化克隆算法将给定的值进行深拷贝。
该方法还支持把原始值中的可转移对象转移到新对象,而不是把属性引用拷贝过去。 可转移对象与原始对象分离并附加到新对象;它们不可以在原始对象中访问被访问到。
——MDN
介绍 structuredClone 方法深拷贝的基础用法
const person = {
name: "Timmy",
gradutionDate: new Date('2017-06-17'),
readingBooks: ['Dream of the Red Chamber']
}
const copied = structuredClone(person)
复制代码
在 console 控制台做个测试:
很多情况下,上述结果确实更符合我们开发者的使用心智!
structuredClone 深拷贝的能力如下:
-
Copy 无限嵌套的对象和数组
-
Copy 循环引用
-
Copy 如下数据类型:
仅支持以下 Error 类型:Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError(或其它会被设置为 Error 的)。
structuredClone 不能做什么:
-
Function 对象是不能被结构化克隆算法复制的;如果你尝试这样子去做,这会导致抛出 DATA_CLONE_ERR 的异常。
-
企图去克隆 DOM 节点同样会抛出 DATA_CLONE_ERR 异常。
-
对象的某些特定参数也不会被保留
介绍 structuredClone 方法转移[可转移对象]的用法
语法:
structuredClone(value, { transfer })
复制代码
Cuando la transferencia de parámetros opcional se pasa al método de clonación estructurada, el objeto transferible solo se puede transferir sin clonarlo. La transferencia hace que el objeto original (las propiedades que contiene) ya no se pueda utilizar.
var uInt8Array = new Uint8Array(1024 * 1024 * 16); // 16MB
for (var i = 0; i < uInt8Array.length; ++i) {
uInt8Array[i] = i;
}
const transferred = structuredClone(uInt8Array, { transfer: [uInt8Array.buffer] });
console.log(uInt8Array.byteLength); // 0
复制代码
Comparación de tres métodos de copia profunda
-
El método JSON.parse(JSON.stringify(obj)) es fácil de usar y tiene buena compatibilidad. Si se trata de una copia profunda de un tipo de datos simple, este método se puede mantener
-
_.copyDeep tiene buena compatibilidad y funciones potentes. No informará errores para los tipos de función, pero la desventaja es que debe prestar atención a la sacudida del árbol, de lo contrario, habrá pérdida de rendimiento.
-
El método StructuredClone es compatible de forma nativa con los navegadores e informará un error para el tipo de función, pero la principal desventaja son los problemas de compatibilidad:
Complemento del método de clonación estructurada: github.com/ungap/struc…
Documentos de referencia:
[1] Objetos de clonación profunda en JavaScript, la forma moderna
[3] structuredClone() - Técnicas de desarrollo web | MDN
[4] Algoritmo de clonación estructurada: referencia de la interfaz API web | MDN
[5] Objetos transferibles - Referencia de la interfaz API web | MDN