There are shallow and deep copies in many development languages, and here's a simple way to differentiate between them in JavaScript and the implementation of deep copies in jquery.
Before you talk about shallow and deep copies, you should be aware of the two concepts of access by value and access by reference in JavaScript.
Access by value is for the base type (string, number, Boolean, null, undefined). The base type is stored in the stack memory in the form of a value, and we manipulate the actual value in the stack memory by the variable.
Accessed by reference for reference types (Object, Array, Date, RegExp, Function). The reference type is stored in the heap memory as an object, and we manipulate the reference of the object in the heap memory through the variable, that is, a pointer is held in the variable, pointing to a location in memory.
--------------------------Split Line--------------------------
The difference between a shallow copy and a deep copy is that for a reference type, a shallow copy copies only one layer of the object's surface, while a deep copy copies all the layers of the object.
What is the difference between these two ways?
As an example:
var arr = [' A ', ' B ']; var newArr = arr; // newarr a copy of arr Console.log (NEWARR); // [' A ', ' B '] Arr.push (' C '); Console.log (NEWARR); // [' A ', ' B ', ' C ']
The above code is a simple shallow copy.
Because Arr is an array, the array internally holds two string-type values. Newarr by directly assigning a reference to the array, when Newarr and Arr point to the same location in memory, the operation of Arr responds to changes in the in-memory array, resulting in newarr changes.
Take a look at the deep copy below:
var arr = [' A ', ' B ']; var newArr = [];newarr[0] = arr[0];newarr[1] = arr[1];console.log (NEWARR); // [' A ', ' B '] Arr.push (' C '); Console.log (NEWARR); // [' A ', ' B ']
The above code is a simple deep copy.
We found that at this point, the change in arr did not affect Newarr, because this time we defined an empty array newarr (which opens up new locations in memory), when Newarr and Arr point to different locations in memory, We then assign the value of the string type in the array and get the last newarr.
So, the copy problem that we encounter in reality will not be this simple array, which might look like this:
var person1 = { ' Mike ', 5, ' Jack ', ' Candy ' };
For this example, if we want to implement a deep copy, we need to traverse all the properties of the Person1. Because name, age is the basic type, so the direct assignment is not a problem, but friends is an array, that is, reference type, then we also need to traverse friends, in case an element of friends array is a reference type, then continue, and so on ...
So, it's not that easy to implement a deep copy, so let's look at how it's handled in jquery.
//This is a way to extend JQuery, Jquery.extend ([Boolean], arg1, arg2, ...)//The first parameter is optional, indicating a shallow copy or a deep copy, the default false//The second parameter is a copy of the storage target (hereinafter referred to as the copy target)//the third and subsequent parameters are copy objects (hereafter referred to as copy objects)Jquery.extend= JQuery.fn.extend =function () { varoptions, name, SRC, copy, Copyisarray, clone, Target= Arguments[0] | |{}, I= 1, Length=Arguments.length, deep=false; if(typeoftarget = = = "Boolean") { deep=Target; Target= Arguments[i] | | {}; I++; } if(typeofTarget!== "Object" &&!jquery.isfunction (target)) {Target= {}; } if(i = = =length) {Target= This; I--; } //Here's the starting point //Traverse Arg2, Arg3, ... for(; i < length; i++) { //If the Copy object is not null and is stored in the variable options if(options = Arguments[i])! =NULL) { //traversing the properties of a copied object for(Nameinchoptions) {src= Target[name];//copy the corresponding attribute value in the targetcopy = Options[name];//Copy the corresponding property value in the object //Prevent circular references if(target = = =copy) { Continue; } //If the deep (Boolean argument) is true, which is to make a dark copy, and the property value in the Copy object is an array or an object if(Deep && copy && jquery.isplainobject (copy) | |(Copyisarray=array.isarray (copy)))) { if(Copyisarray) {//if the property value is an arrayCopyisarray =false; Clone= src && array.isarray (src)? SRC: [];//Copy the attribute value in the target } Else{//if the property value is an objectclone = src && jquery.isplainobject (src)?src: {}; } //recursively calls Jquery.extend () with the property value as a Copy objectTarget[name] =jquery.extend (deep, clone, copy); //otherwise shallow copy}Else if(Copy!==undefined) {Target[name]= copy;//Direct Assignment } } } } //returns the final copy target returnTarget; };
Welcome to add and correct
Shallow and deep copies in JavaScript