Home  >  Article  >  Web Front-end  >  Detailed explanation of shallow copy and deep copy of js objects

Detailed explanation of shallow copy and deep copy of js objects

高洛峰
高洛峰Original
2017-01-03 15:57:121307browse

This article shares the shallow copy and deep copy codes of JavaScript objects for your reference. The specific content is as follows

1. Shallow copy

Copying is to copy the attributes of the parent object. All are copied to the child object.

The following function is for copying:

var Chinese = {
  nation:'中国'
}
var Doctor = {
  career:'医生'
}  
function extendCopy(p) {
    var c = {};
    for (var i in p) { 
      c[i] = p[i];
    }
    c.uber = p;
    return c;
 }

When used, write like this:

var Doctor = extendCopy(Chinese);
Doctor.career = '医生';
alert(Doctor.nation); // 中国

However, there is a problem with such copying. That is, if the properties of the parent object are equal to an array or another object, then in fact, what the child object obtains is only a memory address, not a real copy, so there is a possibility that the parent object has been tampered with.

Please see, now add a "birthplace" attribute to Chinese, its value is an array.

Chinese.birthPlaces = ['Beijing','Shanghai','Hong Kong'];

Through the extendCopy() function, Doctor inherits Chinese.

var Doctor = extendCopy(Chinese);

Then, we add a city to Doctor’s "birthplace":

Doctor.birthPlaces.push('Xiamen') ;

Look at the input results

alert(Doctor.birthPlaces); //Beijing, Shanghai, Hong Kong, Xiamen
alert(Chinese.birthPlaces); //Beijing, Shanghai, Hong Kong , Xiamen

The result is that both their birthplaces have been changed.

So, extendCopy() only copies the basic type of data. We call this copy "shallow copy".

2. Deep copy

Because shallow and deep copies have such disadvantages, let’s take a look at deep copy

The so-called "deep copy" means that it can achieve true Copies of arrays and objects. Its implementation is not difficult, just call "shallow copy" recursively.

function deepCopy(p, c) {
    var c = c || {};
    for (var i in p) {
      if (typeof p[i] === 'object') {
        c[i] = (p[i].constructor === Array) ? [] : {};
        deepCopy(p[i], c[i]);
      } else {
         c[i] = p[i];
      }
    }
    return c;
  }

Look at the usage:

var Doctor = deepCopy(Chinese);

Now, add a property to the parent object with the value as an array. Then, modify this attribute on the child object:

Chinese.birthPlaces = ['北京','上海','香港'];
Doctor.birthPlaces.push('厦门');
 
alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门
alert(Chinese.birthPlaces); //北京, 上海, 香港

This completes the copy;

$.extend()

$.extend() in jquery is the same.

$.extend( [deep ], target, object1 [, objectN ] )

•deep
Type: Boolean
If true, merge into recursion ( Also called deep copy).
•target
Type: Object
Object extension. This will receive the new properties.
•object1
Type: Object
An object containing additional properties merged into the first parameter.
•objectN
Type: Object
Containing additional properties merged into the first parameter A parameter

When we provide two or more objects to $.extend(), all properties of the objects are added to the target object (target parameter).

If only one parameter is provided to $.extend(), this means that the target parameter is omitted. In this case, the jQuery object itself is defaulted to the target object. In this way, we can add new functionality under the jQuery namespace. This is useful for plugin developers who want to add new functions to jQuery.

Remember that the target object (the first parameter) will be modified and will be returned via $.extend(). However, if we want to keep the original object, we can do so by passing an empty object as the target object:

var object = $.extend({}, object1, object2);

In the default case Next, the merging operation via $.extend() is not recursive; if the first object's property is itself an object or array, then it will completely overwrite a property with the same key of the second object. These values ​​will not be merged. You can see this by examining the value of banana in the example below. However, if true is passed as the first argument to the function, recursive merging will be performed on the objects.

Warning: Passing false as the first argument is not supported.

1. Merge two objects and modify the first object.

var object1 = {
 apple: 0,
 banana: { weight: 52, price: 100 },
 cherry: 97
};
var object2 = {
 banana: { price: 200 },
 durian: 100
};
 
// Merge object2 into object1
$.extend( object1, object2 );
 
// Assuming JSON.stringify - not available in IE<8
console.log( JSON.stringify( object1 ) );
//{"apple":0,"banana":{"price":200},"cherry":97,"durian":100}

2. Merge two objects recursively and modify the first object.

var object1 = {
 apple: 0,
 banana: { weight: 52, price: 100 },
 cherry: 97
};
var object2 = {
 banana: { price: 200 },
 durian: 100
};
 
// Merge object2 into object1, recursively
$.extend( true, object1, object2 );
 
// Assuming JSON.stringify - not available in IE<8
console.log( JSON.stringify( object1 ) );
//{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}

3. Merge the defaults and options objects and do not modify the defaults object. This is a commonly used plug-in development model.

var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
 
// Merge defaults and options, without modifying defaults
var settings = $.extend( {}, defaults, options );
 
 
console.log(JSON.stringify( defaults ));
console.log(JSON.stringify( options ));
console.log(JSON.stringify( settings ));
//defaults -- {"validate":false,"limit":5,"name":"foo"}
//options -- {"validate":true,"name":"bar"}
//settings -- {"validate":true,"limit":5,"name":"bar"}

Javascript Determines whether objects are equal

Equality operations in Javascript include "==", "===" are congruent. The difference between the two does not need to be the majority. In this article we How to determine whether two objects are equal will be discussed in the future? You might think that two objects are equal if they have the same properties and their properties have the same values. Then let's demonstrate it through an example:

var obj1 = {
  name: "Benjamin",
  sex : "male"
}
 
var obj2 = {
  name: "Benjamin",
  sex : "male"
}
 
//Outputs: false
console.log(obj1 == obj2);
 
//Outputs: false
console.log(obj1 === obj2);

As you can see from the above example, whether "==" or "===" is used, false is returned. The main reason is that the basic types string and number are compared by value, while objects (Date, Array) and ordinary objects are compared by the address in the memory pointed to by the pointer. Look at the following example:

var obj1 = {
  name: "Benjamin",
  sex : "male"
};
 
var obj2 = {
  name: "Benjamin",
  sex : "male"
};
 
var obj3 = obj1;
 
//Outputs: true
console.log(obj1 == obj3);
 
//Outputs: true
console.log(obj1 === obj3);
 
//Outputs: false
console.log(obj2 == obj3);
 
//Outputs: false
console.log(obj2 === obj3);

The above example returns true because the pointers of obj1 and ob3 point to the same address in memory. Similar to the concepts of value passing and reference passing in object-oriented languages ​​(Java/C++). Because, if you want to judge whether two objects are equal, you must be clear. Do you want to judge whether the attributes of the two objects are the same, or whether the values ​​corresponding to the attributes are the same, or what?

function person(name) { 
  this.name=name; 
} 
 
var p1 = new person("p1"); 
var p2 = new person("p2"); 
 
console.log(p1 == p2); //false 
 
person.prototype.sayHi = function() { 
  // do sayHi here 
} 
 
console.log(p1.sayHi() == p2.sayHi()); //true 
console.log(p1.sayHi() === p2.sayHi()); //true

The above is the entire content of this article. I hope it will be helpful to everyone's learning. I also hope that everyone will support the PHP Chinese website.

For more detailed explanations of shallow copy and deep copy of js objects, please pay attention to the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn