Defining Variables: let/const (better than var)
var
will pollute the global object when called outside a function.
(The global object = window
in browser). In functions, they are function scoped and hoisted.
let/const
will never pollute the global object. Also, they are block scoped.
This means you can isolate let/const
in a if
, switch
, while
, or for
block.
With let
, you can reassign a variable. With const
, you cannot reassign a variable.
WARNING: you can still modify an object or array.
Boolean evaluation
falsy: false
, 0
, ""
, null
, undefined
, NaN
truthy: everything else (including []
, {}
, "0"
, "false"
)
Conditional Evaluation
All of these do short-circuiting (ie: won't try to evaluate eval2 if it doesn't need to)
eval1 || eval2
when eval1
is truthy, return eval1
else return eval2
eval1 && eval2
when eval1
is falsy, return eval1
else return eval2
eval1 ?? eval2
when eval1
is not null
nor undefined
, return eval1
else return eval2
test ? eval1 : eval2
when test
is truthy, return eval1
else return eval2
Classes and “this”
In classes, the this
keyword is determined by the caller.
So with events, this
will be undefined.
To workaround, you can use binding in the constructor:
constructor(props){
super(props);
this.method = this.method.bind(this);
}
Arrow Functions
You can use arrow functions instead of functions. this
is determined by the enclosing container.
// both are equivalent
function add(a, b) {
return a + b;
}
const add = (a, b) => {
return a + b;
};
Shorter Arrow Syntax
If your arrow function only has a single return statement, you can remove it with the curly brackets for the function body.
const add = (a, b) => { return a + b; };
const add = (a, b) => a + b; //equivalent
If the param only has a single argument, then you can omit the round braces.
const double = (a) => a * 2;
const double = a => a * 2; //equivalent
Rest Parameters
function fn(a, b, ...theRest) {
// theRest is an array containing all other arguments
}
Spread Syntax (Arrays, Functions and Objects)
Helps you create new arrays and objects. Also helps you call a function with an existing array.
const numbers = [5, 6, 7];
// spread an existing array into a new one,
// adding a new item at the end ⮯⮯
const moreNumbers = [...numbers, 8];
//this is an normal function ⮯⮯
function fn(a, b, c) { /* code here */ }
// calling previous fn with a spreaded array. ⮯⮯
fn(...numbers);
const employee1 = { name: 'Eric', city: 'Montreal' };
const clonedEmp = { ...employee }; // clone an object
const employee2 = { ...employee, city: 'Dallas' };
// add property to cloned employee ⮭⮭
Destructuring (Arrays and Objects)
Helps you create variables by decomposing the values contained in arrays and objects.
const list = [1, 2, 3];
let [a, , b] = list; // a=1, b=3
[b, a] = [a, b]; // Swap the values, no temp var!
const emp = { firstName: 'Eric', lastName: 'Cote' };
// const firstName='Eric', lastName='Cote' ⮯⮯
const { firstName, lastName } = emp;
// destructuring to alias surname='Cote' ⮯⮯
const { lastName: surname } = emp;
function fn({ firstName, lastName: surname }) {
// destructuring right in fn args ⮭⮭
...
}
Export modules
Modules allows to export and import code right in javascript. There are two types of exports:
- Default Export (only one per module)
- Named Exports
export const x = 5, y = 6;
export function fn() {...};
export class ClassName {...}
// Export list ⮯⮯
export { name1, name2, name3};
// Renaming exports ⮯⮯
export { var1 as name1, var2 as name2};
// Exporting destructured assignments with renaming ⮯⮯
export const { name1, name2: bar } = obj;
// Default exports ⮯⮯
export default expression;
export default function (…) { … } // also class
export default function name1(…) { … } // also class
export { name1 as default, … };
Import modules
Allows you to import code from exported modules. Below, only the first
import React from 'react'; // import the default export
import { useState } from 'react'; //import a named export
// import multiple named export ⮯⮯
import { Button, Input } from 'module-name';
//Use an alias to rename a named export ⮯⮯
import { Button as Btn } from 'react-bootstrap';
// get only what you need from specifice file
// (optimization) ⮯⮯
import { foo, bar } from 'module-name/un-exported/file';
// mix of more complex syntax⮯⮯
import { export1, export2 as alias2 } from 'module';
import defaultExport, { export1, export2 } from 'module';
import defaultExport, * as name from 'module';
import 'module';
// import all named export (expensive, avoid) ⮯⮯
import * as bootstrap from 'react-bootstrap';
// imperative syntax (instead of declarative) ⮯⮯
const promise = import('module');
Closure
A function variable will survive beyond the function scope when referred by an inner function that is returned. Usually, the scope of a var is the enclosing function. But here, the var stays scoped while the returned function stays referenced.
function outer() {
let theVar = 42;
return function inner() {
return theVar;
};
}
const fn = outer();
console.log(fn()); //returns 42!
//theVar stays scoped while fn is reachable.
//this is not the case in languages that
//don't support closures.
React Academy
To get the latest version of this document, visit the handout section of ReactAcademy.live.