Hari Krishna
Hari Krishna

Reputation: 3538

is Object.create() method performs shallow copy?

I am newbee to JavaScript. When I read the Object.create documentation, it is written like 'The Object.create() method creates a new object, using an existing object' (Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create). It do not mention anything about the shallow copy of the object. But when I experimented with below script, I confirmed that, create method is performing shallow copy.

var foo = {
  a : 100,
  details : {
    version : 1.1,
    name : 'Demo of object inheritance'
  },

  printInfo : function(){
    console.log(this.details.version);
    console.log(this.details.name);
    console.log(this.a);
  }

}

var bar = Object.create(foo);

foo.printInfo();
bar.printInfo();

console.log("\n Updating the details and property a of bar object");

bar.details.version = 2.2;
bar.details.name = "Bar object changed the name";
bar.a = 123456;

console.log("\n")
foo.printInfo();
bar.printInfo();

Is my understanding correct? Please point to me any documentation that confirms create() method performs shallow copy.

When I executed in Scratchpad, I seen below output in console.

1.1
Demo of object inheritance
100
1.1
Demo of object inheritance
100

Updating the details and property a of bar object Scratchpad/1:21:1


2.2
Bar object changed the name
100
2.2
Bar object changed the name
123456

Upvotes: 4

Views: 2149

Answers (3)

Deng  Zhebin
Deng Zhebin

Reputation: 1262

It has nothing to with shallow copy. Instead, you have figure it out how Prototype Inheritance works in Javascript world.

To have a better understanding, let's break this down into following 2 parts:

Reading property from child object:

When you try to access a property from a child object, Javascript parser will try to search through up prototype chain until it manages to find it else return undefined if not found.

Write property in child object

It will first try to locate that the object to which the your targeted property belongs, and then directly set that property on that object.

Let's take part of your code as example:


bar.details.version = 2.2;

 What Javascript parser does:
  1. First, details will be located through prototype chain searching and it will be found on foo (ie: bar.details === foo.details)

  2. Second, version is directly set on details object(that's why this.details.version and this.details.name are both "unexpectedly" changed as you saw in your result and as a result bar.details.version === foo.details.version === 2.2))


bar.a = 123456;

What Javascript parser does:

Before anything gets started, bar is already located and there's no need to search though prototype chain, as a result, a will be directly set on the bar (ie. that's why only bar.a is affected with foo.a still holding the origin value:123456)

Upvotes: 1

jonathangersam
jonathangersam

Reputation: 1147

create method is performing shallow copy.

-- EDIT --

Nope, it may seem that way but the term shallow copy would be inaccurate. It would be more in line with prototypal inheritance MDN article here

Given an object oA that has a name property, function Object.create(oA) creates a new object oB. Trying to access property oB.name would look up the prototype chain until it finds one on its prototype at oA.name.

Sample code below:

/* create one object adam */
const adam = {
	name: 'Adam',
} 
console.log(`does adam have own 'name' property?`, adam.hasOwnProperty('name')) // true

/* create new object bob, whose prototype 'ancestor' is adam */
const bob = Object.create(adam)
console.log(`does bob have own 'name' property? (1)`, bob.hasOwnProperty('name')) // false; the 'name' prop is on adam

/* assigning 'name' on bob doesn't change adam's name, it just 'shadows' it -- accessing 'name' on bob returns the one on bob */
bob.name = 'Bob'
console.log(`does bob have own 'name' property? (2)`, bob.hasOwnProperty('name')) // now true

/* adam and bob now each have their own 'name' property */
console.log(adam.name) // Adam
console.log(bob.name)  // Bob

/* show the relationship of adam and bob */
console.log(`is adam a prototype 'ancestor' of bob?`, adam.isPrototypeOf(bob)) // true, linked via Object.create()
console.log(`is bob a prototype 'ancestor' of adam?`, bob.isPrototypeOf(adam)) // false, the prototype points one way

Hope this helps. Cheers,

Upvotes: -1

Sandip Nirmal
Sandip Nirmal

Reputation: 2459

Object.Create does not copy anything at all, it just sets the passed object as the prototype of a new object:

const person = {name: 'Alex', age: 29}
const newPerson = Object.create(person)

console.log(newPerson)

enter image description here

In order to make a shallow copy, you can use Object.assign.

const newPersonObj = Object.assign({}, person)
console.log(newPersonObj)

This will create entirely new copy. enter image description here

Upvotes: 3

Related Questions