Read full article on the Infragistics blog
“In JavaScript, Object’s assign method copies source object’s own enumerable properties to a target object, and returns that target object “
There are two important keywords in the above sentence:
- Enumerable
- Own
Before we go ahead and understand purpose of Object.assign, it is essential that we really understand these two words, enumerable properties and own properties. Let us see them one by one:
A JavaScript object could have either enumerable or non-enumerable properties. However, by default when you create property on an object, it is enumerable. Enumerable means you can enumerate through those properties. Let us understand it through code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const babycat = { | |
age: '1', | |
color: 'white' | |
} | |
for (var prop in babycat) { | |
console.log(prop); | |
} |
There are two properties in babycat object. By default both are enumerable, hence as the output of for..in loop, you will get both age and name printed.
Now let us change default enumerable behavior of age property using Object.defineProperty method.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const babycat = { | |
age: '1', | |
color: 'white' | |
} | |
Object.defineProperty(babycat, 'age', { enumerable: false }); | |
for (var prop in babycat) { | |
console.log(prop); | |
} |
We have changed enumerable of age property to false, so as output, you will get only color printed. Hence, age is no longer an enumerable property of babycat object.
Another keyword in above sentence is own properties. To understand it, you need to understand object prototype chain. All JavaScript objects are part of a prototype chain, hence can access properties of its prototype’s also. So, own properties are those properties, which are particular to the object and not from the prototype chain. Let us understand own properties through code examples,
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const cat = { | |
name: 'foo' | |
} | |
const babycat = { | |
age: '1', | |
color: 'white' | |
} | |
//babycat.__proto__ = cat; // I love this more | |
Object.setPrototypeOf(babycat, cat); | |
for (var prop in babycat) { | |
console.log(prop); | |
} |
In above code snippet, there are two objects cat and babycat. In addition, [[Prototype]] property of babycat object is set to cat object. When you print properties of the babycat object using for..in loop, you will find as output age, color, name printed as shown in below image:
What is happening here? Well, JavaScript prints all properties from the prototype chain. However, only age and color are, own properties of babycat object.
As of now, you should have understood own properties and enumerable properties in context of a JavaScript object. So let us revisit first statement of this post,
“In JavaScript, Object’s assign method copies source object’s own enumerable properties to a target object, and returns that target object “
You should able to infer what exactly above sentence implies. Consider code below :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const cat = { | |
name: 'foo' | |
} | |
const babycat = Object.assign({}, cat); | |
for (var prop in babycat) { | |
console.log(prop + ':' + babycat[prop]); | |
} |
Using Object.assign() method , we are copying cat object own enumerable properties to babycat object. Here, cat object is source and babycat object is target. You will get output printed as below:
The Object.assign() method uses [[Get]] on the source object and [[set]] on the target object and invokes setter and getter to perform the task. Essentially, it assigns properties values from source to target object. It does not create new property in the target object.
As of now you know purpose of the Object.assign() method. Let us examine some variations while copying properties from source object to a target object.
Same Properties in both target and source object
If target object has same properties as of source object, then Object.assign() method will override target object properties. To understand it consider code listing below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const cat = { | |
name: 'foo', | |
age: 9 | |
} | |
const babycat = Object.assign({ age: 1 }, cat); | |
for (var prop in babycat) { | |
console.log(prop + ':' + babycat[prop]); | |
} |
There is age property in both target object and source object. While copying properties in target object the Object.assign() method will override target object age property, hence you will get output as shown in the below image :
Leave a Reply