Site icon i2tutorials

Javascript-Object Copying

Javascript-Object Copying

 

The assignment operator doesn’t provide a copy of an object. It only assigns a reference to it.

 

let obj = {
 a: 1,
 b: 2,
};
let copy = obj;

obj.a = 5;
console.log(copy.a);
// Result
// a = 5;

 

The obj variable is a container and for the new object initialized. The copy variable is pointing to the same object and it is a reference to that object.

So basically this { a: 1, b: 2, } object is saying: There are now 2 ways to gain access to me.

1.you have to pass through the obj variable.

2.the copy variable either way you still get to me and anything you do to me via these ways (gateways) will affect me.

 

4 different techniques for copying objects in JavaScript:

 

 

Shallow copy:

 

This shallow copy, an object means to duplicate the top-level properties, and the nested object is shared between the original -(source) and the copy(target).

 

Using Object.assign() method:

 

This method provided to copy the values of all enumerable values owns properties objects from one or more source objects to a target object.

 

let obj = {
 a: 1,
 b: 2,
};
let objCopy = Object.assign({}, obj);
console.log(objCopy);
// Result - { a: 1, b: 2 }

 

Deep Copying Objects:

 

It will be duplicate every object it encounters. The copy and the original(source) object will not share anything, so it will be a copy of the original.

 

Using JSON.parse(JSON.stringify(object)):

 

This fixes the issue we had earlier. Now newObj.b is a copy and not a reference!. This is a way to deep copy objects.

 

let obj = {
 a: 1,
 b: {
  c: 2,
  },
}

let newObj = JSON.parse(JSON.stringify(obj));

obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 2 } } (New Object Intact!)

Immutable: ✓

 

Assign:

 

we will take different sources and shallow copy their respective properties to a single target, therefore this is going to look very much like an implementation of Object.assign.

 

describe('assign v1 (copy props)', () => {
it('assigns objects properties correctly', () => {
  const obj1 = { one: true }
  const obj2 = { two: true }
  expect(assignv1(obj1, obj2)).toEqual({ one: true, two: true })
 })
it('mutates the target', () => {
  const obj1 = { one: true }
  const obj2 = { two: true }
  assignv1(obj1, obj2)
  expect(obj1).toEqual({ one: true, two: true })
  const obj3 = { three: true }
  const obj4 = { four: true }
  const obj5 = assignv1({}, obj3, obj4)
  expect(obj5).not.toBe(obj3)
  expect(obj5).not.toBe(obj4)
  expect(obj5).toEqual({ three: true, four: true })
 })
})
describe('assign v2 (spread operator)', () => {
it('assigns objects properties correctly', () => {
  const obj1 = { one: true }
  const obj2 = { two: true }
  expect(assignv2(obj1, obj2)).toEqual({ one: true, two: true })
 })
it('does not mutate the target', () => {
  const obj1 = { one: true }
  const obj2 = { two: true }
  const obj3 = assignv2(obj1, obj2)
  expect(obj1).not.toEqual({ one: true, two: true })
  expect(obj3).not.toBe(obj1)
  expect(obj3).toEqual({ one: true, two: true })
 })
})

 

Merge:

 

It works like assign but instead of replacing properties and in the target it actually adjoins them. If a value is either an array / an object the function proceeds to merge the properties recursively as well. Non-object-like properties (not arrays and not objects) are simply assigned an undefined property are omitted altogether.

 

const testMerge = (mergeFn: MergeFn) => {
const obj1 = {
 prop1: {
  prop2: {
   prop3: [1, 2, 6],
   prop4: true,
   prop5: false,
   prop6: [{ abc: true, abcd: true }],
  },
 },
}
const obj2 = {
 prop1: {
  prop2: {
   prop3: [1, 2, undefined, 4, 5],
   prop4: false,
   prop6: [{ abc: false }],
 },
 prop7: true,
 },
}
expect(mergeFn({}, obj1, obj2)).toEqual({
 prop1: {
  prop2: {
   prop3: [1, 2, 6, 4, 5],
   prop4: false,
   prop5: false,
   prop6: [{ abc: false, abcd: true }],
  },
   prop7: true,
  },
 })
}

describe('merge v1 (recursively)', () => {
it('it merges provided objects into one', () => {
  return testMerge(mergev1)
})
})
describe('merge v2 (flatten props)', () => {
it('it merges provided objects into one', () => {
  return testMerge(mergev2)
 })
})

 

Exit mobile version