While working on Javascript we have to deal with objects as it's a building block of the Javascript. Knowing how to use the objects effectively makes your code more readable, efficient, and bug-free. In this blog, we are going to see a few good practices while working with objects in Javascript. So let's get started!
Tip 1: Use the literal syntax for object creation
This seems to be a small change while initialising the objects variable, but after knowing this information you will better understand why this is important.
// not recommended
const item = new Object();
// good practice
const item = {};
Simplicity and Readability: The literal syntax provides a concise and intuitive way to define objects. It is easier to read and understand compared to the Object constructor, which requires invoking a function with the new keyword.
Consistency: Using the literal syntax ensures consistency in code style throughout your project. Most developers are accustomed to seeing objects defined using literal syntax, making the code more familiar and easier to maintain.
Performance: Creating objects with the literal syntax is faster compared to using the Object constructor. The literal syntax directly creates the object without invoking any additional functions or constructors.
Prototype Chain Preservation: When using the Object constructor, the newly created object doesn't inherit from the global Object prototype. In contrast, when using the literal syntax, the object is created with the correct prototype chain intact.
Immutability: When using the literal syntax, it's easier to create immutable objects by using techniques such as Object.freeze()
or ES6's object spread syntax ({...})
, which can make the object properties read-only. This immutability helps prevent unintended modifications to the object.
Syntax Errors Avoidance: The literal syntax allows for more flexibility when defining objects, such as using computed property names ({[key]: value})
, shorthand property syntax ({key})
, or object methods ({method() {}})
. These features are not available when using the Object constructor.
While there may be some rare cases where using the Object constructor is necessary (e.g., when creating objects with specific prototypes), in general, the literal syntax offers a simpler, more readable, and performant way to create objects in JavaScript.
Tip 2: Use computed property names
function getKey(k) {
return `${k}_key`; //generates key name dynamically
}
// not recommended
const obj = {
id: 1,
name: 'Foo',
};
obj[getKey('enabled')] = true;
// good practice!
const obj = {
id: 1,
name: 'Foo',
[getKey('enabled')]: true, // computed property syntax
};
This will allow you to define all the properties at once while creating the object.
Tip 3: Use object method and property shorthand
- use object method shorthand
// looks ugly
const obj = {
value: 1,
addValue: function (value) {
return this.value + value;
},
};
// looks clean!
const obj = {
value: 1,
addValue(value) {
return this.value + value;
},
};
- use property value shorthand
const property = 'property';
// looks ugly
const obj = {
property: property,
};
// good practice
const obj = {
property,
};
Group all shorthand properties at the beginning of your object declaration.In this way it's easier to see which properties are using the shorthand.
Tip 4: Provide quotes for properties with invalid identifiers
There is no need to quote all the properties defined inside the object. This hampers the readability and the object looks bulky. If you are using any invalid identifiers such as identifiers with kebab cases, then you can quote that particular property.
// bulky
const obj = {
'prop1': 1,
'prop2': 2,
'prop-3': 3,
};
// good practice!
const obj = {
prop1: 1,
prop2: 2,
'prop-3': 3,
};
Tip 4: shallow/deep copy object to avoid object mutability
There are a few tricks and methods which allow the object to be copied to another object variable to avoid mutating the original object. Based on the requirement we can create a shallow copy or deep copy of the original object or else completely store the reference of the original object into another object variable.
- avoid using
Object.assign()
in this way
const originalObj = { a: 1, b: 2 };
const copiedObj = Object.assign(originalObj, { c: 3 }); // this mutates `originalObj`
delete copiedObj.a; // this will be deleted from the originalObj as well!!!!
- shallow copy using
Object.assign
const originalObj = { a: 1, b: 2 };
const copiedObj = Object.assign({}, originalObj, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }
delete copiedObj.a
console.log(originalObj) // {a: 1, b: 2}
console.log(copiedObj) // {b: 2, c: 3}, 'a' is deleted from copiedObj
- shallow copy using spread object syntax
const originalObj = { a: 1, b: 2 };
const copiedObj = {...originalObj, c: 3} // copy => { a: 1, b: 2, c: 3 }
delete copiedObj.a
console.log(originalObj) // {a: 1, b: 2}
console.log(copiedObj) // {b: 2, c: 3}, 'a' is deleted from copiedObj
- deep copy using
JSON.parse
andJSON.stringify
const originalObj = { a: 1, b: {
b1: 1,
b2: 2
} };
const copiedObj = JSON.parse(JSON.stringify(originalObj)) // copy => { a: 1, b: {b1: 1, b2: 2} }
delete copiedObj.b.b1
console.log(originalObj) // {a: 1, b: {b1: 1, b2: 2}}
console.log(copiedObj) // {a: 1, b: { b2: 2}}