David Alsh
David Alsh

Reputation: 7685

A more aesthetic way of copying an object literal?

This is client side. Webpack, Babel and Babel Imports.

My project has a folder called "models" which contains object literals as definitions of the expected JSON results from endpoints.

The objects only contain strings, ints, booleans and arrays/objects which contain those data types

eg:

{
    name: "String"
    age: 35,
    active: true,
    permissions: [
        { news: true }
    ]
}

When I want to use a model definition, in order to ensure I don't have issues with references, I must use:

let newObject1 = Object.assign({}, originalObj )

or

let newObject2 = JSON.parse( JSON.stringify( originalObj ))

I find this a bit ugly and it pollutes my code a bit.

I would love the ability to use the new keyword on object literals, but of course that's not a thing.

let clone = new targetObj

What's the most aesthetic way to handle the cloning of an object literal without creating a reference?

Upvotes: 0

Views: 58

Answers (2)

Ben West
Ben West

Reputation: 4596

const model = () => ({
    name: 'string',
    age: 20,
    array: [ 1, 2, 3 ]
});

let newObject = model();

You won't have the pleasure of using new - see trincot's answer for that - but you don't have to worry about nested objects (assign) or feel gross (stringify + parse).

Upvotes: 1

trincot
trincot

Reputation: 351338

The JavaScript way of implementing such object "templates" are constructors:

function Original() {
    this.name = "String";
    this.age = 18;
    this.active = true;
    this.permissions =  [
        { news: true }
    ];
}

var obj = new Original();

console.log(obj);

Or, in ES6 class syntax:

class Original {
    constructor() {
        this.name = "String";
        this.age = 18;
        this.active = true;
        this.permissions =  [
            { news: true }
        ];
    }
}

let obj = new Original();

console.log(obj);

Be aware that Object.assign will only create a shallow copy, so it would not copy the permissions array, but provide a reference to the same array as in the original object.

const originalObject = {
    name: "String",
    age: 35,
    active: true,
    permissions: [
        { news: true }
    ]
};

let obj1 = Object.assign({}, originalObject);
let obj2 = Object.assign({}, originalObject);

// change a permission:
obj1.permissions[0].news = false;
// See what permissions are in obj2:
console.log(obj1.permissions);

Upvotes: 2

Related Questions