2019年1月17日 星期四

How to clone an object in Javascript with Object.defineProperties?

TL;DR

Sometimes we want to clone an object in JS, we will use something like:


const obj = {foo:'bar'};
const newobj = {};
for (const key in obj){
    newobj[key] = obj[key];
}

This will work fine under most circumstances, since you might never adjust the property flags of the object. Also, when we create an object property, theare default to true, so everything is "default normal." And you might even not know there are such flags. Property flags, in brief, are metadata for the property in the object. They define the configuration of the property such as if the property is writable/enumerable/configurable.

Here are some simple explanation about the flags:

Writable: can reassign value or not.
Enumerable: can enumerate it with for...in loop or not.
Configurable: can change the flags shown above and this flag or not.

Okay, the problem with the above cloning code is that when someone changes the flags to non-default values, and you unconsciously clone the object without knowing those property flags. In a nutshell, if you want to clone an object along with the flags, please do as following:


let newobj = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));

Here we use Object.defineProperties(object, descriptors) and Object.getOwnPropertyDescriptors(object) to accomplish this. The former will define properties for the objects in the first argument ( here is an empty object literal. ) with the property descriptors in the second argument ( here is the latter function getOwnPropertyDescriptors. ). However, although the code is cleaner, this method should be employed only when you really need to clone the property descriptors since it is slower and not straight-forward enough.

For more on Property flags and descriptors:

沒有留言:

張貼留言