Méthode d'implémentation : 1. Utilisez "Object.assign()" pour implémenter une copie superficielle, qui copie les propriétés de première couche de l'objet. 2. Utilisez l'opérateur spread pour implémenter une copie superficielle, la syntaxe est "{ ...obj };". 3. Utilisez "JSON.stringify()" pour implémenter la copie approfondie. Le principe est de sérialiser un objet en chaîne JSON, de convertir le contenu de l'objet en chaîne et de l'enregistrer sur le disque, puis d'utiliser JSON.parse(. ) La désérialisation transforme une chaîne JSON en un nouvel objet.
L'environnement d'exploitation de ce tutoriel : système Windows 7, ECMAScript version 6, ordinateur Dell G3.
Avant de comprendre la copie profonde et la copie superficielle des objets, nous devons d'abord connaître les types de données de JavaScript. JavaScript contient deux types de données principaux, types de données de base et types de données de référence.
Les types de données de base sont des données simples dont les valeurs sont stockées sur la pile. Par exemple :
let a = '123'; let b = 2;
Les types de données de base en JavaScript sont String, Number, Boolean, Undefined, Null, Symbol
(nouveau dans ES6). Les types de données de base sont accessibles par valeur. Par exemple, si la variable a est affectée à la variable b, la modification de la valeur de la variable a n'affectera pas la valeur de la variable b. Elles sont indépendantes les unes des autres et ne s'affectent pas. Les deux variables ont respectivement alloué de l'espace dans la pile de stockage. String、Number、Boolean、Undefined、Null、Symbol
(ES6新增的)。基本数据类型都是按值访问的。比如把变量a赋值给变量b,修改变量a的值不会影响变量b的值,它们两个是互相独立的,互不影响。在存储栈中这个两个变量分别分配了空间。
let a = '123'; let b = a; a = 10; console.log(a) // 10 console.log(b) // 123
引用类型值是引用类型的实例,它是保存在堆内存中的一个对象,引用类型是一种数据结构,最常用的是Object,Array,Function
类型,另外还有Date,RegExp,Error
等,ES6同样也提供了Set,Map2
种新的数据结构。
let obj1 = { a: '1' } let obj2 = obj1; obj1.a = '2'; console.log(obj1.a); // 2 console.log(obj2.a) // 2
看看上面的代码,发现和基本数据类型的结果不太一样,我们把obj1赋值给了obj2,修改obj1的值,obj2的值也发生了改变。由于引用数据类型的值是存储的堆内存中,而在栈内存中存储了指向堆内存中的指针(地址),我们上面代码中的赋值操作只是赋值了指针(地址)。而指针指向的堆内存还是同一个。
浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
JavaScript中常见的一些浅拷贝方法
let target = {}; // 目标对象 let source = { a: 1 } // 原对象 Object.assign(target, source); console.log(target.a); // 1 source.a = 2; console.log(source.a); // 2 console.log(target.a); // 1
Object.assign()是一个浅拷贝,它值拷贝了对象的第一层属性。如果对象的属性仍然是一个对象,就无法实现拷贝了。
除了Object.assign()
能实现对象的浅拷贝之外,扩展运算符var cloneObj = { ...obj }; Array.prototype.slice()
、也都是浅拷贝。
function shalldowCopy(source) { let obj = Array.isArray(origin) ? [] : {}; // 目标对象 for(let prop in source) { if (src.hasOwnProperty(prop)) { target[prop] = source[prop]; } } return target; }
测试一下
var sourceObj = { a:1, arr: [2,3] }; var targetObject = shallowCopy(sourceObj);
因为浅拷贝只会将对象的各个属性进行依次复制,并不会进行递归复制,而 JavaScript 存储对象都是存地址的,所以浅拷贝会导致 sourceObj.arr
和 targetObject.arr
指向同一块内存地址。所以导致的结果就是:
shallowObj.arr[1] = 5; obj.arr[1]; // = 5
深拷贝就是指将一个对象完整的复制一份新的出来,在堆内存中开辟一份新的存储空间。如果对象的属性是对象,也依旧会拷贝。
JavaScript中常见的一些深拷贝方法
JSON.stringify()
是目前前端开发过程中最常用的深拷贝方式,原理是把一个对象序列化成为一个JSON字符串,将对象的内容转换成字符串的形式再保存在磁盘上,再用JSON.parse()
let target = {}; // 目标对象 let source = { a: 1, b: { d: 3 } } // 原对象 let targetStr = JSON.stringify(source); let target = JSON.parse(targetStr); console.log(target); // {a: 1, b: {d: 3}} source.b.d = 10; console.log(source); // {a: 1, b: {d: 10}} console.log(target); // {a: 1, b: {d: 3}}
Object, Array, Function
, et il existe également des Date, RegExp, Error
, etc. ES6 fournit également de nouveaux types de Set, Map2
structure de données. /** * 深拷贝 * @param {*} origin */ function deepCopy(origin) { let obj = Array.isArray(origin) ? [] : {}; if (origin && typeof origin === 'object') { for(let key in origin) { let item = origin[key]; if (item && typeof item === 'object') { obj[key] = deepCopy(item); } else { obj[key] = item; } } } return obj; }
Copie superficielleLa copie superficielle est une copie bit par bit d'un objet. Elle crée un nouvel objet qui a une copie exacte des valeurs de propriété de l'objet d'origine. Si l'attribut est un type de base, la valeur du type de base est copiée ; si l'attribut est une adresse mémoire (type référence), l'adresse mémoire est copiée, donc si l'un des objets change cette adresse, cela affectera l'autre. objet. Quelques méthodes de copie superficielle courantes en JavaScript
var sourceObj = { a:1, arr: [2,3] }; var targetObject = deepCopy(sourceObj); shallowObj.arr[1] = 5; obj.arr[1]; // = 3
Object.assign()
qui peut réaliser une copie superficielle d'objets, l'opérateur d'expansion var cloneObj = { ...obj }; code >, sont également des copies superficielles. 🎜<h3 data-id="heading-4">🎜Implémentez manuellement une copie superficielle🎜🎜rrreee🎜Testez-la🎜rrreee🎜Parce que la copie superficielle copiera uniquement chaque attribut de l'objet dans l'ordre et ne copiera pas les magasins JavaScript de manière récursive. objets à des adresses, donc une copie superficielle fera que <code>sourceObj.arr
et targetObject.arr
pointeront vers la même adresse mémoire. Le résultat est donc : 🎜rrreeeJSON.stringify()
sont actuellement dans le front-end processus de développement La méthode de copie profonde la plus couramment utilisée, le principe est de sérialiser un objet dans une chaîne JSON, de convertir le contenu de l'objet sous forme de chaîne et de l'enregistrer sur le disque, puis d'utiliser JSON.parse() code> Désérialiser la chaîne JSON en un nouvel objet🎜rrreee🎜🎜Implémenter manuellement une copie complète🎜🎜rrreee🎜Testez-la🎜rrreee🎜【Recommandations associées : 🎜Tutoriel vidéo javascript🎜, 🎜Vidéo de programmation🎜】🎜
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!