JS quick bytes -I
This is the first part of the series which I will be publishing which will provide an insight on following best practices on JS.
References in JS
- Use
constfor all of your references; avoid usingvar.
Any idea why?
This would ensure that no reassignment happens to the references which can further lead to bugs. - If in case reassignment is required, then let should be used instead of var as let is block scoped.
Objects
- Use computed property names when creating objects with dynamic property names as they allow you to define all the properties of an object in one place.
function getKey(key1) {
return `a key named ${key1}`;
}
// bad
const obj = {
id: 1,
name: 'India',
};
obj[getKey('enabled')] = true;
// good
const obj = {
id: 5,
name: 'India',
[getKey('enabled')]: true,
};2. Use object method shorthand.
// bad
const foo= {
value: 1,
add: function (value) {
return foo.value + value;
},
};
// good
const foo= {
value: 10,
add(value) {
return foo.value + value;
},
};3. Use property value shorthand as its shorter and descriptive. Also group your shorthand properties at the beginning of your object declaration. Why? It’s easier to tell which properties are using the shorthand.
const name = 'Medium';
//bad
const obj = {
name: name
};//good
const obj = {
name
};//Groupingconst name= 'Sam';
const age= 35;
// bad
const obj = {
bloodGrp: 'B+',
lovesBaseBall: true,
name,
lovesCricket: true,
age};
// good
const obj = {
name,
age,
bloodGrp: 'B+',
lovesBaseBall: true,
lovesCricket: true
};
4. Only quote properties that are invalid identifiers. In general we consider it subjectively easier to read. It improves syntax highlighting, and is also more easily optimized by many JS engines.
// bad
const badIdentifier= {
'foo': 3,
'bar': 4,
'data-bad': 5,
};
// good
const goodIdentifier = {
foo: 3,
bar: 4,
'data-good': 5,
};5. As Object’s methods like hasOwnProperty, propertyEnumerable , etc may be shadowed by properties on the object in question — consider { hasOwnProperty: false } - or, the object may be a null object (Object.create(null)).
// badGet Memosha Sinha’s stories in your inbox
Join Medium for free to get updates from this writer.
console.log(object.hasOwnProperty(key));
// good
console.log(Object.prototype.hasOwnProperty.call(object, key));
// best
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
console.log(has.call(object, key));
/* or */
import has from 'has'; // https://www.npmjs.com/package/has
console.log(has(object, key));
6. Prefer the object spread operator over Object.assign to shallow-copy objects. Use the object rest operator to get a new object with certain properties omitted.
// very bad
const original = { a: 1, b: 2 };
const copy = Object.assign(original, { c: 3 }); // this mutates `original` object which may lead to bug
delete copy.a; // so does this
// bad
const original = { a: 1, b: 2 };
const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }
// good
const original = { a: 1, b: 2 };
const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }
const { a, ...noA } = copy; // noA => { b: 2, c: 3 }Arrays
- Prefer literal syntax for array creation.
As mentioned in es-lint : Use of theArrayconstructor to construct a new array is generally discouraged in favor of array literal notation because of the single-argument pitfall and because theArrayglobal may be redefined. The exception is when the Array constructor is used to intentionally create sparse arrays of a specified size by giving the constructor a single numeric argument.
// bad
const items = new Array();
// good
const items = [];- Use Array#push instead of direct assignment to add items to an array.
const arr= [];
// bad
arr[arr.length] = 'item1';
// good
arr.push('item1');- 4.3 Use array spreads
...to copy arrays.
// bad
const len = items.length;
const itemsCopy = [];
let i;
for (i = 0; i < len; i += 1) {
itemsCopy[i] = items[i];
}
// good
const itemsCopy = [...items];- 4.4 To convert an iterable object to an array, use spreads
...instead ofArray.from.
const foo = document.querySelectorAll('.foo');
// good
const nodes = Array.from(foo);
// best
const nodes = [...foo];- 4.5 Use
Array.fromfor converting an array-like object to an array.
const arrCopy= { 0: 'foo', 1: 'bar', 2: 'baz', length: 3 };
// bad
const arr = Array.prototype.slice.call(arrCopy);
// good
const arr = Array.from(arrCopy);- 4.6 Use
Array.frominstead of spread...for mapping over iterables, because it avoids creating an intermediate array.
// bad
const baz = [...foo].map(bar);
// good
const baz = Array.from(foo, bar);- 4.7 Use return statements in array method callbacks. It’s ok to omit the return if the function body consists of a single statement returning an expression without side effects, refer eslint:
array-callback-return
// good
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
// good
[1, 2, 3].map((x) => x + 1);
// bad - no returned value means `acc` becomes undefined after the first iteration
[[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
const flatten = acc.concat(item);
});
// good
[[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
const flatten = acc.concat(item);
return flatten;
});
// bad
inbox.filter((msg) => {
const { subject, author } = msg;
if (subject === 'Mockingbird') {
return author === 'Harper Lee';
} else {
return false;
}
});
// good
inbox.filter((msg) => {
const { subject, author } = msg;
if (subject === 'Mockingbird') {
return author === 'Harper Lee';
}
return false;
});- 4.8 Use line breaks after open and before close array brackets if an array has multiple lines
// bad
const arr = [
[0, 1], [2, 3], [4, 5],
];
const objectInArray = [{
id: 1,
}, {
id: 2,
}];
const numberInArray = [
1, 2,
];
// good
const arr = [[0, 1], [2, 3], [4, 5]];
const objectInArray = [
{
id: 1,
},
{
id: 2,
},
];
const numberInArray = [
1,
2,
];




