JavaScript #
I have not learnt JavaScript properly. Proceed at your own risk.
Why does Swift by Sundell not use any client-side JavaScript? | Swift by Sundell
(Maybe) useful resources #
- (List) Learn JavaScript – Free JS Courses for Beginners
- (List) JavaScript Practice Exercises for All Levels - Snipcart
- Eloquent JavaScript
- getify/You-Dont-Know-JS at 1st-ed
- JavaScript: The Good Parts
- JavaScript Tutorial
- JavaScript Patterns
- JavaScript: The Definitive Guide, 6th Edition
- Perfect JavaScript(日文版)
- Effective JavaScript(日文版)
- (Paid) JSchallenger
- 前端的设计模式系列
- An Introduction to D3.js
Exercises #
- JavaScript Exercises - W3Schools
- TheOdinProject/javascript-exercises
- wesbos/JavaScript30: 30 Day Vanilla JS Challenge
Operators #
| Arithmetic | Logical | Relational (numeric and string) |
|---|---|---|
+ addition | & and | > greater than |
- subtraction | || or | < less than |
* multiplication | ~ not | >= > or equal |
/ division | ^ xor | <= < or equal |
% remainder | c ? t : f ternary | == equal |
** power | != not equal | |
+ string concatenation | === strict equal | |
+ convert to number | !== strict not equal |
Variables #
Number / string:
"use strict";
let count = 0;
count = count + 1;
console.log(count);
// 1
Array #
Also see: Array methods - javascript.info
let myArray = [1, true, "what"];
// or
let myArray = new Array(1, true, "what");
console.log(myArray[0]);
// 1
Push, pop, shift, unshift:
let myArray = ["this", "is", "life"];
myArray.push("end"); // append to end (-1)
console.log(myArray.pop()); // read and remove from end
// end
myArray.unshift("whether"); // prepend to start (0)
console.log(myArray.shift()); // read and remove from start
// whether
Slice:
let myArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(myArray.splice(3, 2)); // take b indices that are >=a
// 3, 4
console.log(myArray);
// 0, 1, 2, 5, 6, 7, 8, 9
Pop-ups #
Prompt:
let popUp = prompt("Who are you?");
// user is prompted to input
console.log(popUp);
// prints what user has typed
Confirm:
let popUp = confirm("Is this thing on?");
// user is prompted to choose yes or no
console.log(popUp);
// prints true or false
Alert:
let popUp = alert("Hello!");
// user can only click confirm
console.log(popUp);
// prints nothing
Statements #
If #
if () {
...
} else if () {
...
} else {
...
}Switch #
let variable = 3;
switch(variable) {
case 1:
...
break;
case 2:
...
break;
default:
...
break;
}Loop #
for (let i = 0; i < 3; i++) {
...
}const array = [1, 2, 3, 4, 5];
for (let item of array) {
console.log(item);
}let object = {
firstName: "John",
lastName: "Smith",
}
for (let prop in object) {
console.log(prop);
}let i = 10;
while (i > 0) {
...
i = i - 1;
}let i = 10;
do { // is always executed at least once
...
i = i - 1;
} while (i > 0);Break and continue #
See also Python #break, pass, continue
Break: Stop the whole {...}
for (let i = 1; i < 11; i++) {
console.log(i);
break;
}
// 1
Continue: Stop current iteration, start next iteration
for (let i = 1; i < 11; i++) {
if (1 == i % 2) {
continue;
}
console.log(i);
}
// 2
// 4
// 6
// 8
// 10
Label for break and continue #
Break nested loops:
outer: for (let i = 0; i < 3; i++) {
...
for (let j = 0; j < 3; j++) {
...
if (...) break outer;
}
}Continue nested loops:
let n = 16;
outer: for (let i = 2; i <= n; i++) {
for (let j = 2; j < i; j--) {
if (i % j === 0) {
continue outer;
}
}
console.log(i);
}
// 2 3 5 7 11 13
Objects #
let person = {
firstName: "John",
lastName: "Smith",
age: 20,
employed: true,
bio() {
console.log(`${this.firstName} is ${this.age} years old.`);
},
};Always check property exists when looping:
for (let char in person) {
if (person.hasOwnProperty(char)) {
console.log("The " + char + " of personObject is " + person[char] + ".");
}
}Functions #
Ref:
- function expression - JavaScript | MDN
- Arrow function expressions - JavaScript | MDN
- IIFE - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
Declaration (named) #
- Can be called earlier than it is defined
- Not anonymous
function func(x) {
// ...
}async function func(x) {
// ...
}Arrow expression (named or unnamed) #
returnis required for multiple-line arrow functions.- Anonymous (even if assigned to a variable name)
(x, y) => x + y;
(x, y) => {return x + y;}
(x) => {
// ...
return;
};const func = (x) => x + y;
const func = (x) => {return x + y;}
const func = (x) => {
// ...
return;
};async (x) => {
// ...
};
const func = async (x) => {
// ...
return;
};IIFE (Immediately Invoked Function Expression) #
- Can be anonymous or not
(function () {
// ...
})();(async function () {
// ...
})();Classes #
Constructor functions #
const Person = function(name, age) {
this.name = name;
this.age = age;
this.describe = function() {
return this.name + ", " + age + " years old.";
}
}
let alice = new Person("Alice", 25);
let bob = new Person("Bob", 10);
console.log(alice.describe()); // Alice, 25 years old.
console.log(bob.describe()); // Bob, 10 years old.
Inheritance #
let Person = function() {};
Person.prototype.initialize = function(name, age) {
this.name = name;
this.age = age;
}
let Teacher = function() {};
Teacher.prototype = new Person();
Teacher.prototype.teach = function(subject) {
console.log(this.name + " is now teaching " + subject);
}
let somebody = new Teacher();
somebody.initialize("Jane", 45);
somebody.teach("Inheritance");Destructuring #
const person = {
head: {
eyes: 'x',
mouth: {
teeth: 'x',
tongue: 'x'
}
},
body: {
shoulders: 'x',
chest: 'x',
arms: 'x',
hands: 'x',
legs: 'x'
}
};
let {legs: myLegs} = person.body;
console.log(myLegs);
// x
const numbers = ['2', '3', '4'];
let [, , thirdPosition] = numbers;
console.log(thirdPosition);
// 4
Context #
What are some use cases for call, apply, and/or bind? : learnjavascript
bind #
Returns a new function
let person = {
name : "John"
};
function printName() {
console.log(this.name);
}
let boundPrintName = printName.bind(person);
boundPrintName(); // "John"
call & apply #
Calls the original function with a different this
let person = {
name : "John"
};
function printName() {
console.log(this.name);
}
printName.call(person); // "John"
Events #
Event listener #
const btn = document.querySelector("#btn");
btn.addEventListener("click", () => {
alert("Hello World");
});Remove event listener from within:
element.addEventListener("click", function callback(event) {
...
if (condition >= 5 ) {
element.removeEventListener("click", callback);
}
};Other methods #
Inline event handler (not recommended):
<button onclick="alert('Hello World')">Click Me</button>Event handler property:
const btn = document.querySelector("#btn");
btn.onclick = () => alert("Hello World");Promise/Async #
Promises #
Refs:
- Promises - Learn JavaScript - Free Interactive JavaScript Tutorial
- Promise() constructor - JavaScript | MDN
Usage:
const promise1 = new Promise((resolve, reject) => { resolve(); return; });promise1.then((result) => { ... });setTimeout(functionToRun, delay)
function upperCaseAsync(s) {
// 1. the function is executed
// 2. initialise the promise
return new Promise((resolve, reject) => {
// 3. wait 100 ms and then run if (1s = 1000ms)
setTimeout(() => {
if (s) {
// if receive something, then resolve
resolve(s.toUpperCase());
} else {
// if receive null, then reject
reject("No string received!");
}
}, 100);
});
// 4. finish promise construction
}
upperCaseAsync("here").then(console.log);
upperCaseAsync("there").then((result) => {
console.log(result);
}).catch((error) => {
console.log("Error received:", error);
});
upperCaseAsync(null).catch((error) => {
console.log("Error received:", error);
});async & await (implicit Promise) #
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function uppercaseString(s) {
await sleep(100);
return s.toUpperCase();
}
uppercaseString("here").then(console.log);Snippets #
Add line breaks for dummies #
Ref: CSS word wrap / line break on underscores in addition to whitespace and hyphens - Stack Overflow
(function() {
var i, text, code, codes = document.getElementsByTagName('code');
for (i = 0; i < codes.length;) {
code = codes[i];
if (code.parentNode.tagName !== 'PRE' && code.childElementCount === 0) {
// add line break before
code.innerHTML = code.innerHTML.replace(/(?<!^|\.|\s)(\.|\(|{|\\|@)/g, '<wbr />\$1');
// add line break after
code.innerHTML = code.innerHTML.replace(/(,|})(?!$|\s)/g, '\$1<wbr />');
// add line breaks around
code.innerHTML = code.innerHTML.replace(/(?<!^|-|\.|\s)(_|-|=|\/)(?!$|\s)/g, '<wbr />\$1<wbr />');
}
i++;
}
})();Button #
index.html html<button id="increment-btn" onclick="increment()">INCREMENT</button>
<script src="index.js"></script>function increment() {
console.log("The button was clicked.");
}Delay #
// send notification after 5 sec
var notify = function() {
console.log("Done!");
}
setTimeout(notify, 5000);
// or
setTimeout(function() {
console.log("Done!");
}, 5000);Dialog (Modal) on-load #
Ref: Modals Will Never Be The Same - HTML dialog Element
HTML:
<dialog id="dialog" class="modal">
<form method="dialog">
<p>This is a modal which appears immediately at page loading.</p>
<button type="button" id="dialog--confirm">Confirm</button>
<button type="button" onclick="location.href='javascript:history.back()'">Go Back</button>
</form>
<hr />
</dialog>JS:
document.addEventListener('DOMContentLoaded', function(event) {
const body = document.body;
body.classList.add("modal-open");
const dialog = document.getElementById("dialog");
dialog.show();
const button = document.getElementById("dialog--confirm");
button.addEventListener("click", function(event) {
dialog.close();
body.classList.remove("modal-open");
});
});Inject CSS #
Ref: Inject CSS stylesheet as string using Javascript - Stack Overflow
/**
* Utility function to add CSS in multiple passes.
* @param {string} styleString
*/
function addStyle(styleString) {
const style = document.createElement('style');
style.textContent = styleString;
document.head.append(style);
}
addStyle(`
body {
color: red;
}
`);
addStyle(`
body {
background: silver;
}
`);Rich link copy button #
Tooltip #
Ref: Building a fully-accessible help tooltip – Sara Soueidan, inclusive design engineer
TBA.