Maison > Article > interface Web > Explication détaillée des exemples de copie profonde et superficielle d'objets JavaScript
D'un point de vue hiérarchique, la copie d'objets peut être simplement divisée en copie superficielle et copie profonde. Comme son nom l'indique, la copie superficielle fait référence à la copie uniquement des propriétés d'une couche d'objets et non à la copie des propriétés des objets dans la couche. objet. Copie approfondie des objets. Les propriétés des objets imbriqués dans l'objet seront copiées. Cet article est un résumé de certaines de mes expériences en matière de copie d'objets, de la copie superficielle à la copie approfondie. Les amis intéressés peuvent apprendre ensemble
Avant-propos
. D'un point de vue hiérarchique, la copie d'objets peut être simplement divisée en copie superficielle et copie profonde. Comme son nom l'indique, la copie superficielle fait référence à la copie uniquement des propriétés d'une couche d'objets et ne copiera pas les propriétés de. les objets dans l'objet. La copie approfondie de l'objet copiera les propriétés des objets imbriqués.
Lors de la copie d'un objet, en plus de copier les propriétés de l'objet, vous devez également déterminer si la propriété constructeur de l'objet est conservée et si chaque type de données (les types de données courants en Javascript incluent String , Number, Boolean, Data, RegExp, Array, Function, Object) permettent tous une copie correcte. Dans le projet, nous pouvons décider du degré de réplication à atteindre en fonction de la situation réelle.
Cet article est un résumé de mon expérience dans la copie d'objets, de la copie superficielle à la copie profonde, de la copie d'attributs simples uniquement à la copie d'attributs complexes tels que Function et RegExp, et progresse couche par couche. S'il y a quelque chose d'inapproprié dans la déclaration, veuillez le signaler, je vous en serais très reconnaissant.
Texte
Copie superficielle
La copie superficielle copiera uniquement chaque attribut de l'objet dans séquence , ces propriétés ne seront pas copiées de manière récursive. Vous trouverez ci-dessous une simple implémentation de copie superficielle.
//对象浅复制 function shadowCopy(obj){ if(typeof obj !== 'object') return obj; for(var prop in obj){ if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; } } return newObj; }
En regardant attentivement, il n'est pas difficile de trouver les défauts de la méthode ci-dessus :
1. La copie superficielle du tableau ne peut pas être implémentée correctement
2. L'opération de copie perd le constructeur des attributs de l'objet
D'accord, nous avons maintenant découvert le problème. Il ne nous reste plus qu'à le résoudre de manière ciblée, et une méthode assez parfaite de copie superficielle d'objets est née !
//对象浅复制 function shadowCopy(obj){ if(typeof obj !== 'object') return ; var newObj; //保留对象的constructor属性 if(obj.constructor === Array){ newObj = []; } else { newObj = {}; newObj.constructor = obj.constructor; } for(var prop in obj){ if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; } } return newObj; }
Testez-le dans le navigateur :
var arr1 = [0,1,2]; console.log(arr1); console.log(shadowCopy(arr1)); var arr2 = [0,1,2,[3,4,5]], arr2Copy = shadowCopy(arr2); console.log(arr2); console.log(arr2Copy); arr2Copy[3][0] = 6; console.log(arr2[3][0]); //6
Bien, vous pouvez correctement implémenter la copie de tableau ! et Et le constructeur est conservé, mais si vous faites attention, vous devez avoir découvert que arr2Copy[3] et arr2[3] de l'objet copié superficiellement pointent vers le même objet. Changer l'un d'eux changera également l'autre. Ce que nous voulons réaliser, c’est la réplication, mais ce n’est pas la réplication !
C'est l'un des inconvénients de la copie superficielle. Voyons comment la copie approfondie résout ce problème.
Copie approfondie
La copie approfondie nécessite des couches de récursion, copiant toutes les propriétés de l'objet, y compris les propriétés des propriétés de l'objet....(Halo ~)
Si vous avez simplement besoin de copier simplement les propriétés d'un objet sans tenir compte de son constructeur ou des types de données spéciaux tels que les fonctions, les éléments réguliers et les données, alors voici une petite astuce pour la copie approfondie, juste deux lignes de code :
function deepCopy(obj){ if(typeof obj !== "object"){ return ;} var str = JSON.stringify(obj); return JSON.parse(str); }
Dans la plupart des cas, ce qui précède peut répondre aux exigences, mais parfois, nous devons prendre en compte des types de données spéciaux tels que les fonctions et les expressions régulières, ou les environnement actuel Lorsque JSON n'est pas pris en charge, la méthode ci-dessus ne s'applique pas. À l'heure actuelle, nous pouvons implémenter la copie approfondie d'objets par récursivité, comme suit :
function deepCopy(obj){ if(typeof obj !== "object"){ return ;} var newObj; //保留对象的constructor属性 if(obj.constructor === Array){ newObj = []; } else { newObj = {}; newObj.constructor = obj.constructor; } for(var prop in obj){ if(typeof obj[prop] === 'object'){ if(obj[prop].constructor === RegExp ||obj[prop].constructor === Date){ newObj[prop] = obj[prop]; } else { //递归 newObj[prop] = deepCopy(obj[prop]); } } else { newObj[prop] = obj[prop]; } } return newObj; }
Utilisez d'abord l'exemple ci-dessus pour tester :
Super ! La copie de tableaux multidimensionnels peut être réalisée correctement, puis voir si la copie de fonctions et d'expressions régulières peut être réalisée :
function Person(name){ this.name = name; this.age = age; this.search = new RegExp(name); this.say = function(){ console.log(this.name + "今年" + this.age + "岁了"); } } var p1 = new Person("Claiyre",20), p2 = deepCopy(p1); console.log(p1); console.log(p2); p2.age = 22; p1.say(); p2.say();
Achèvement satisfaisant ! !
Après un peu de rangement, on peut obtenir une fonction de copie d'objet js plus générale :
function deepCopy(obj){ var newObj = obj.constructor === Array ? []:{}; newObj.constructor = obj.constructor; if(typeof obj !== "object"){ return ; } else if(window.JSON){ //若需要考虑特殊的数据类型,如正则,函数等,需把这个else if去掉即可 newObj = JSON.parse(JSON.stringify(obj)); } else { for(var prop in obj){ if(obj[prop].constructor === RegExp ||obj[prop].constructor === Date){ newObj[prop] = obj[prop]; } else if(typeof obj[prop] === 'object'){ //递归 newObj[prop] = deepCopy(obj[prop]); } else { newObj[prop] = obj[prop]; } } } return newObj; }
Conclusion
Le cœur du langage de programmation orienté objet est constitué d'objets. Par conséquent, une compréhension approfondie des opérations associées des objets et une comparaison verticale des similitudes et des différences sont extrêmement bénéfiques pour le processus d'apprentissage.
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!