Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cloning Non enumerable properties in javascript

Tags:

javascript

I have all non - enumerable properties in object, I want to clone that object.

My problem non-enumerable properties are not getting cloned.

Take below example

 Object.defineProperty(this, 'prop', {
        get: function () {
            return prop;
        },
        set: function (value) {
            prop= value;
        }
    });

   Object.defineProperty(this, 'newprop', {
        get: function () {
            return newprop;
        },
        set: function (value) {
            newprop= value;
        }
    });

For example I have above two properties in my object doing clone using following methods, my properties are not getting cloned I believe it is because they are non - enumerable.

   var newObject = $.extend({},oldObject);
   var newObject= Object.assign({},oldobject);

How do I copy non-enumerable properties in javascript.

like image 235
Max Maddy Avatar asked Jul 11 '16 21:07

Max Maddy


People also ask

What are non-enumerable properties in JavaScript?

Objects can have properties that don't show up when iterated through the particular object using Object. keys() or for...in loop. Those type of properties are called as non-enumerable properties.

How do you copy properties from one object to another in JavaScript?

Object.assign() The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.

How many ways we can clone object in JavaScript?

JavaScript provides 3 good ways to clone objects: using spread operator, rest operator and Object.

What is the most efficient way to deep clone an object in JavaScript?

Using the Json. Among the above mentioned three ways, for an object to be deep cloned, JSON. stringify() and JSON. parse() functions are used. The parse() method accepts a JSON String as a parameter and creates a JavaScript object accordingly.


2 Answers

If one or more properties aren't enumerable, how do you want to auto-magically enumerate them?

Since you know their names, you should do something like this:

var sourceObj = this;
var targetObj = {};

["prop", "otherProperty"].forEach(function(property) {
    targetObj[property] = sourceObj[property]; 
});

Or you can build the whole property name array whenever you define a non-enumerable property:

   var propertyNames = [];

   Object.defineProperty(this, 'newprop', {
        get: function () {
            return newprop;
        },
        set: function (value) {
            newprop= value;
        }
    });
    propertyNames.push("newprop"); // <---


   Object.defineProperty(this, 'newprop2', {
        get: function () {
            return newprop;
        },
        set: function (value) {
            newprop= value;
        }
    });
    propertyNames.push("newprop2"); // <---

propertyNames.forEach(function(property) {
    targetObj[property] = sourceObj[property]; 
});

Alternate approach: Object.getOwnPropertyNames

The Object.getOwnPropertyNames() method returns an array of all properties (enumerable or not) found directly upon a given object.

Maybe this is the best approach. Object.getOwnPropertyNames gets the name of own object's properties either if they're enumerable or not. That is, you can avoid building the whole propertyNames array, and this approach should be fine with you because you said that all properties aren't enumerable:

var sourceObj = this;
var targetObj = {};    

Object.getOwnPropertyNames(sourceObj).forEach(function(property) {
    targetObj[property] = sourceObj[property]; 
});
like image 188
Matías Fidemraizer Avatar answered Oct 02 '22 09:10

Matías Fidemraizer


You can use Object.defineProperties and Object.getOwnPropertyDescriptors() function

The Object.defineProperties() method defines new or modifies existing properties directly on an object, returning the object.

The Object.getOwnPropertyDescriptors() method returns all own property descriptors of a given object.

So, you can add the properties of the original object into an empty object, as follow

var source_obj = this
var cloned_obj = Object.defineProperties({}, Object.getOwnPropertyDescriptors(source_obj));
like image 25
Abanoub Ghadban Avatar answered Oct 02 '22 10:10

Abanoub Ghadban