-
Prefer the use of
let
andconst
thanvar
.var
should be used mostly in loops, to avoid a new variable each cycle.- ex.
for (var i = 0; i < 10000; ++i)
wil create variablei
once, even though each cycle will "redefine" variable i, beacuse of how javascript works, it will just reuse the previous one, and use it for the rest of the loop - ex.
for (let i = 0; i < 10000; ++i)
will create variablei
scoped to each cycle. So this will mean it will actually create 10,000 variables, one per cycle. let
is preferred because it is scoped to the current block, allowing nested blocks to access it, but preventing from redefining an upper level variable or being accessed from outside of the expected scope.- ex.
var i = 5; if (i>0) { var i = 10; console.log(i); }; console.log(i);
=> output:10
,10
In this example even though a newvar
was declared in the if block, it just reused the previous one. And so the i on the outer scope is affected - ex.
let i = 5; if (i>0) { let i = 10; console.log(i) }; console.log(i);
=> output:10
,5
In this example eachlet
definition was conserved in their scope even when a newlet
was declared with the same name within the if scope. If by accident you used avar
that was already declared before, you would overwrite it and pretty much introduce hard to track bugs. By usinglet
you prevent this to happen, but remember it is still a code smell to have many variables with the same name.
-
Assignment
- When reading many fields from an array or object is better to use Destructuring assignment, this will lead to cleaner code and avoid mess.
- ex. Destructuring -> Magic Numbers
// You have a coordinate and need to get the value of `x` and `y` individually.
// This approach takes 3 lines, and you are using magic numbers to the the values from the array
const coord = [10, 4];
const x = coord[0];
const y = coord[1];
// With this approach is clearer which element is `x` and which is `y`, and also it only took 2 lines of code
const coord = [10,4];
const [x, y] = coord;
// You have to get the three first three elements of a queue
// 5 lines of code, more magic numbers, and somethings that feels a little bit wrong.
const queue = ['id1', 'id2', 'id3', 'id4', 'id5']; // Probably many more
const q1 = queue[0];
const q2 = queue[1];
const q3 = queue[2];
const restOfQueue = queue.slice(3);
// Note that you can also set default values with this approach
const foobar = ['foo'];
const [foo, bar='bar'] = foobar;
console.log(foo); // outputs 'foo'
console.log(bar); // outputs 'bar'
// With the destructuring approach, everything is done in 2 lines, and it gets pretty clear what everything means.
const queue = ['id1', 'id2', 'id3', 'id4', 'id5']; // Probably many more
const [q1, q2, q3, ...restOfQueue] = queue;
// My personal favorite, when getting many fields of an object as variables (ex props), including default variables
// Component that receives a team and a user as props;
// team = { name: 'Progressly', memberCount: 10 }
// user = { name: 'Ale', age: 21, notes: undefined }
function MyComponent ({team, user}) { // this is the same as function MyComponent(props) { const team = props.team; const user = props.user; }
const {name: teamName, memberCount} = team; // teamName = team.name ~ memberCount = team.memberCount
const {name, age, notes = 'no notes'} = user;
return <p>{name} is {age} years old and is member of {teamName}, she has {memberCount} teammates. {notes}</p>;
// <p> Ale is 21 years old and is member of Progressly, she has 10 teammates. no notes
}
// Also in react class way
class AnotherComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
const {team, user} = this.props;
const {name: teamName, memberCount} = team; // teamName = team.name ~ memberCount = team.memberCount
const {name, age, notes = 'no notes'} = user;
return <p>{name} is {age} years old and is member of {teamName}, she has {memberCount} teammates. {notes}</p>;
// <p> Ale is 21 years old and is member of Progressly, she has 10 teammates. no notes
}
}