JavaScript

Last updated 2 days ago

Resources

Type

MDN

Array

MDN

Date

MDN

Object

MDN

String

MDN

JSON

MDN

Set

MDN

RegExp

MDN

Destructuring Assignment

MDN

const

MDN

let

MDN

export

MDN

Style Guides

Personal Opinion

Google

AirBNB

jQuery

Standard

Semicolons

Required

Required

Required

Required

Not Required

import/export

DO NOT USE

Use

require()

Custom Solution

DO NOT USE

Trailing Commas

Required

Required

Required

camelCase

objects, functions, instances

blank

objects, functions, instances

strict mode

Begin files with:

'use strict';

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

Arrow functions: () => {}

const a = (param1, param2) => {
return param1 + param2;
}
const b = (param1, param2) => param1 + param2;

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Array

Test Array

Array.isArray(array)

This does not work to test if its an array.

if (array) {
// empty arrays evaluate as false
}
if (array && array.length > 0) {
// you may still want to capture the array
}

Clone an array

const clone = array.slice(0);

Iterate keys in an array (for...in)

const array = ['x', 'y', 'z'];
for (const key in array) {
console.log(key);
}
0
1
2

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

Iterate values in an array (for...of)

const array = ['x', 'y', 'z'];
for (const value of array) {
console.log(value);
}
x
y
z

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of

Appending/merging arrays together

const array3 = array1.concat(array2);

String

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String

UTF Support

https://stackoverflow.com/questions/16293923/does-v8-have-unicode-support https://github.com/v8/v8/blob/master/include/v8.h

Object

Clone an object

const clone = Object.assign({}, original);

Doesn't do deep cloning.

Iterate keys in an object (for...in)

const object = {x: 'a', y: 'b', z: 'c'}
for (const key in object) {
console.log(`${key}: ${object[key]}`);
}

Result:

x: a
y: b
z: c

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of

Iterate values in an object (for...of)

Do not use `(for...of)` with `objects`. This will fatal with: Safari: ``` TypeError: page[Symbol.iterator] is not a function. (In 'page[Symbol.iterator]()', 'page[Symbol.iterator]' is undefined) ``` Chrome: ``` Uncaught TypeError: page[Symbol.iterator] is not a function ```

Set

  • Use size vs length.

  • To add: use add

  • To remove/delete: use delete

Set Cloning

const new = new Set(old);

Or if enabled:

const new = ...old

Set Iteration

for (let value of set.values()) {
...
}

To Array

Array.from(new Set())

Differences

https://github.com/aizatto/nodejs/blob/master/src/fn.js#L42

function setMath<T>(a: Set<T>, b: Set<T>) {
return {
remove: [...a].filter(x => !b.has(x)),
add: [...b].filter(x => !a.has(x)),
};
}

Async

async () => {
await new Promise(...);
const [
result1,
result2,
] = await Promise.all([
new Promise(),
new Promise(...)],
);
return value;
}

Promises

When you start chaining a lot of promises and passing variables around, consider usings aysnc instead.

Pay attention to the style, because it's really stupid.

const start = new Promise((resolve, reject) => {
xhr.get(url)
.success((result) => resolve(result))
.failure((error) => reject(error));
});
const afterStart = (startResult) => new Promise((resolve, reject) => {
});
start
.then(afterStart)
// Always start on a new line, its easier to catch
// Always use a Promise or only { Promise.all([]) }, its eaiser to catch
.then() => new Promise((resolve, reject) => {
})
.catch((error) => {
console.log(error);
});
  • Always have a catch() to ensure you can see all errors.

window

window.location.hash

console.log(window.location.hash);

Results:

#array

Results will always be prefixed with #

scroll

Scroll to a part of the screen.

window.location.hash = '#object'

trailing commas

http://exploringjs.com/es2016-es2017/ch_trailing-comma-parameters.html

Regex

Matching one string

"aaaa".match(/[a]/)

Result:

["a"]

Matching multiple substrings

"a a123a a123a b123b c".match(/a(123)a/g)

Result:

["a123", "a123"]

Note the trailing /g

  • You cannot select individual groups while using g

Simple Assert

input = "a b c d e";
main(input) {
...
}
assert(expected, input) {
console.log(input);
actual = main(input);
result = expected === actual;
console.log(result);
if (!result) {
console.log(actual);
console.log(expected);
}
}
// Case 1
assert(expected, input);
// Case 2
assert(expected2, input2);
// Case 3
assert(expected3, input3);

Warning: querystring.stringify does not stringify deeply nested objects.

Classes

class Animal {
constructor() {
}
}
class Cat extends Animal {
constructor(props) {
super(props)
}
}

Modules

  • AirBNB JavaScript Style Guide: Modules

    • 10.1 Always use modules (import/export) over a non-standard module system.

    • 10.2 Do not use wildcard imports.

    • 10.6 In modules with a single export, prefer default export over named export.

      • Interpretation: multiple exports allowed

  • Confusing as hell

    • ESM vs CommonJS vs ES6

If using export default use import var from module:

export const foo = 42
export default 21;

If you want the 21, use import bar from './input';

import barImport from './input';
console.log(barImport); // 21
const barRequire = require('./input');
console.log(barRequire);
/*
{
foo: 42,
default: 21,
}
*/

Notes

export const types = () => {}

is different from

export function types() { }

Cons / Dislikes

  • No conventions.

  • Not standardized.

  • No consistency in online resources.

    • Lots of outdated online resources.

    • The fact that AirBNB has 20 pages on how to write JavaScript is insane.

  • No first class Enums

  • No types. Can be handled by Flow or TypeScript

  • Callback hell (work around with Promises, async and await, but its not supported everywhere)

  • Inconsisent: Array.length vs Set.size

    • Like wtf?

  • All the problems of a loosely typed language.

    • Hard to scale as a language, due to no types.

    • Hard to refactor.

  • Inconsistencies in coding style amongst the community

  • JS Modules are confusing

  • Requires high code coverage due to inconsistencies.

  • Changing babel flags can make your code run differently

    • Requires high code coverage to ensure it does as expected.

  • You need tools like lodash for basic stuff (bucketing items in in an array, groupBy)

  • Requires a lot of tooling to maintain JavaScript

  • Was design for client side browsing, not server side

  • It has both null and undefined

  • No native sprintf

  • Browser support is differet. I ran into a problem with fetch() not being supported. https://github.com/github/fetch#browser-support

  • Requires a lot of static analysis tools.

Flow vs TypeScript

Flow

https://flow.org/en/docs/config/

https://github.com/facebook/relay/blob/master/.flowconfig https://github.com/facebook/react/blob/master/.flowconfig https://github.com/graphql/graphql-js/blob/master/.flowconfig

ESLINT

Alternatives

Frameworks

ORM

To add

  • async/await