Also checkout how to do things with Vanilla JS: </dom>.
-
{}
is object;[]
is array -
null
is a value missing intentionally -
undefined
is a value missing unintentionally if () { ... } else { ... }
- Regular functions:
function f() { ... }
. - Prefer class rather over prototype
- JavaScript classes are just functions
obj.toString() => '[object Object]'
- Version constraint:
~
patch,^
minor, and use this semver calculator
The return value of function must use return
:
function identity(x) {
return x
}
const object = {a: 1, b: 2, c: 3, d: 4}
object.a
1
object['a']
1
'use strict'
turn on the Stricit mode.
- No need to use
;
to end the line - Octal literals not allowed.
- Cannot introduce global variable.
-
delete
can only remove key from object. -
===
to compare things - Regular Expression
Debug with debugger
, console.log()
, console.trace()
.
How did JavaScript’s console.log get its name?
document.querySelector
document.getElementById
node.getAttribute
-
insertAdjacentHTML
to add HTMLbeforebegin
/afterbegin
/beforeend
/afterend
to any element
- Arithmetic on
undefined
returnsNaN
- Operation on a
NaN
returnsNaN
-
isNaN(undefined)
is true -
Number.isNaN
is the fixed version ofisNaN
Disallow specific global variables -
Number.isFinite
overnumber === Infinity
-
Number.MIN_SAFE_INTEGER
andNUmber.MAX_SAFE_INTEGER
.Number.isSafeInteger
checks if number is within the safe range.
-
Object.keys
to list all keys of given object. Modern JavaScript guarantee object key ordering
const name = 'Juanito'
const loginCounts = {[name]: 5}
loginCounts.Juanito
5
const users = [
{ name: 'Juanito', age: 15 },
{ name: 'Bella', age: 16 },
]
function age(user) {
return { [user.name]: user.age }
}
age(users[0])
const name = 'Juanito'
const age = 36
const user = {name, age};
[user.name, user.age]
['Juanito', 36]
const user = {
get name() { return 'Juanito' }
}
user.name
'Juanito'
const user = {
realName: 'Juan',
set name(newName) { this.realName = newName }
}
user.name = 'Juanito'
user.realName
'Juanito'
Don’t use var
, use let
(can change) and const
(cannot change).
-
let
is properly scoped inside block of code{ ... }
. -
const
variable cannot be redefined. But you can still mutate the variable elements. E.g. change the elements ofconst
-defined array
const
will find the nearest definitions.
ESLint rule: Require Guarding for-in (guard-for-in)
for (.. in ..) {}
iterates over keys in array.
Skips undefined
and null
elements.
const keys = []
const letters = []
letters[1] = 'a'
for (const key in letters) {
keys.push(key)
}
keys
['1']
for (.. of ..) {}
iterates over values in array.
Returns undefined
for undefined
or null
elements.
const keys = []
const letters = []
letters[1] = 'a'
for (const key of letters) {
keys.push(key)
}
keys
[undefined, '1']
forEach
method will skip over empty slots.
var users = [
{name: 'Lia'},
{name: 'Yejin'},
]
var names = []
users.forEach(user => {
names.push(user.name)
})
names
'str'
"str"
`str` // called template literals
Template literals can do interpolation:
`1+1=${1+1}`
${1+1}
calls toString()
on computed value.
template literals can have newline:
const signoff = `
Best,
Juanito
`
dedent can remove leading whitespaces.
[1, 2].toString()
'1,2'
({a: 1}).toString()
'[object Object]'
Example of sum
function:
function sum(...numbers) {
return numbers.reduce((x, y) => x + y, 0)
}
- Arrow functions:
const f = () => { ... }
. (nothis
,this
will be the nearestfunction
)
Last resort: Use bind
to set a function’s this
.
...
is called spread operator.
Must come last and only used once in function signature, comes after positional arguments.
f(...args) {
}
Pass in rest args to function
function add(x, y) {
return x+y
}
const numbers = [1, 9]
add(...numbers)
The *
says numbers
function is a generator function.
function* numbers() {
yield 1
yield 2
}
for (const n of numbers) {
console.log(n)
}
Array.from(numbers)
=> [1, 2]
function hello(){
return 'Hello'
}
hello`world!`
=> `Hello`
To deconstruct literal and interpolated values from string:
function extractArguments(strings, ...values) {
return {
first: strings,
second: values,
}
}
extractArguments`1${2}3`
{ first: ['1', '3'], second: [2] }
-
new Array(1)
=>[empty]
(empty slot) -
empty
is the representation, butundefined
will be used as return value fornew Array(1)[0]
=>undefined
- Create array with prefilled value:
new Array(3).fill(1)
- Find index
arr.indexOf(e)
,-1
if not found -
findIndex(element => expr)
to find element’s index satisfyexpr
,findIndex
returns first match - Copy array with
slice
- Use
push
to add an element to array,push
returns the new length of changed array - Use
join
to join elements of array - Use
flat
to flatten one level;flat(Infinity)
to flat recursively Source -
flat
+map
=>flatMap
-
map
to do something on argument and returns new array -
map
skips empty slots -
reduce
skips empty slots -
filter
skips empty slots - use
slice
+sort
if does not want to change original array - sort array:
arr.sort((a, b) => a - b)
-
null
andundefined
become empty strings whenjoin
- spread operator
...
const middleNumbers = [6, 7] const numbers = [5, ...middleNumbers, 8]
-
['a', 'b'].reduceRight((a, x) => a + x)
=>'ba'
Array’s type is 'object'
instead of 'array'
.
const obj = {a: 1, b: 2}
const keys = []
for (const key in obj) {
keys.push(key)
}
typeof keys
=> 'object'
Array looks like an implcity object where key is the index:
Object.keys(['a', 'b', 'c'])
['0', '1', '2']
- Prefer
Set
has()
over['a', 'b'].includes('c')
(O(N)
) -
in
operator asks whether thearr[0]
has something:0 in arr
const letters = ['a', 'b']
const [a, b] = letters
// Skip value
const letters = ['a', 'b', 'c']
const [a, , c] = letters
['a', 'c']
// Supply value when missing
const letters = ['a', 'b']
const [a, b, c='C'] = letters
['a', 'b', 'C']
// Deconstruct over Supplied value
const letters = ['a', 'b', 'c']
const [a, b, c='C'] = letters
['a', 'b', 'c']
// String can also be deconstructed
const letters = 'xy'
const [x, y] = letters
x
// => 'x'
some
always returns false
for an empty array.
[].some(x => x > 0)
true
[10, 20].some(x => x > 10)
false
every
always returns true
for an empty array.
[].every(x => x > 0)
true
[10, 20].every(x => x > 10)
false
There is no none
function in JavaScript. we can implement like so:
!arr.some(f)
![2,3,4].some(number => number === 1)
JSON.stringify— A key with undefined
value will be removed from resulting JSON
JSON.stringify(obj, f)
. JSON.stringify
preserves key order.
JSON.parse—parse
will look for a toJSON
key in object
class Animal {
constructor(name) {
this.name = 'name'
}
}
new Animal().name
Methods on class is called Static Methods.
class User {
static getUserName(user) {
return user.name
}
}
class Person extends Animal {
constructor() {
super(name + ' the human')
}
}
const names = new Set([1,1,2])
names.add()
names.delete()
names.clear()
function benchmark(f) {
const start = new Date().getTime()
for (let i=0; i<1000000; i++) {
f()
}
const end = new Date().getTime()
return end - start
}
- Cannot define another class inside a class
- Set union, intersection, difference are
O(N)
, array’s areO(N*N)
class User {
constructor(name, email) {
this.name = name
this.email = email
this.admin = false
}
}
class Admin extends User {
constructor(name, email) {
super(name, email)
this.admin = true
}
}
const admin = new Admin('Juanito', '[email protected]', true)
admin.admin
=> true
admin instanceof User
=> true
Class will capture surrounding function’s name
function createUser(name) {
class User {
constructor() {
this.name = name
}
}
return new User()
}
createUserr('Guest').name
const user = {
'user name'() { return 'Juanito' }
}
user['user name']()
=> 'Juanito'
const set1 = new Set([1, 2, 3])
const set2 = new Set([2, 3, 4])
const unionSet = new Set([...set1, ...set2]);
[unionSet.has(1), unionSet.has(4)]
Array.from(unionSet)
[1, 2, 3, 4]
const set1 = new Set([1, 2, 3])
const set2 = new Set([2, 3, 4])
const intersectionSet = new Set(
Array.from(set1).filter(n => set2.has(n))
);
Array.from(intersectionSet)
[2, 3]
const set1 = new Set([1, 2, 3])
const set2 = new Set([2, 3, 4])
const differenceSet = new Set(
Array.from(set1).filter(n => !set2.has(n))
);
Array.from(differenceSet)
[1]
-
Symbol.toStringTag
=>Symbol(Symbol.toStringTag)
- Built-in
toString()
=>this[Symbol.toStringTag]