Scope
Hoisted
mean the declaration is effectively at the beginning of the scope, so it can even be accessed before its declaration. However the value relies on the definition. Both variable and function declarations are hoisted.
function test() {
console.log(a);
console.log(foo());
var a = 1;
function foo() {
return 2;
}
}
test();
is equivalent to:
function test() {
var a;
function foo() {
return 2;
}
console.log(a);
console.log(foo());
a = 1;
}
test();
- Function declarations are hoisted.
- Class declarations are hoisted.
- If no semicolon at the end of the line, one will be added automatically.
Data Type
- Primitive
- Boolean
- Null
typeof null === 'object'
- Undefined
- Number
type of NaN === 'number'
- Use
Number.isNaN
instead ofisNaN
, as the latter coerces the type of argument - Convert variable to a Number object:
Number(var)
- As numbers are all double-precision floating point, to achieve accurate result, scaling numbers with fractions to integers. Because integer arithmetic is accurate.
- Use
parseInt
/Number.parseInt
(ES6+) to convert number of another radix to decimal.
- String
- Symbol (ES6)
- Object
- Array
Array.isArray
- Function
- Array
- Equality
- Primitives like strings and numbers are compared by their value, while objects like arrays, dates, and plain objects are compared by their reference.
Function
- An arrow function does not have its own this; the this value of the enclosing lexical context is used i.e. Arrow functions follow the normal variable lookup rules. So while searching for this which is not present in current scope they end up finding this from its enclosing scope .
Class
ES5
/*
* Parent class, should be abstract
*/
function PageElement() {
this._$loadingIndicator = null;
this._disabled = false;
}
// instance methods, _ prefix by convention means private
PageElement.prototype._showLoading = function ($element) {
this._$loadingIndicator = IU.addWaitingIndicatorToElement($element);
return this._$loadingIndicator;
};
PageElement.prototype._createIndicator = function (id) {
this._$loadingIndicator = IU.createWaitingIndicator(id);
return this._$loadingIndicator;
};
PageElement.prototype._hideLoading = function () {
if (this._$loadingIndicator) {
IU.removeIndicator(this._$loadingIndicator);
}
};
PageElement.prototype._toggle = function ($element, state) {
$element.prop("disabled", !state);
};
/*
* Child class, should be abstract
*/
function Button(selector, container) {
// Constructor
this._selector = selector; // fields
this._$container = container;
this._$btn = this._$container.find(this._selector);
}
Button.prototype = Object.create(PageElement.prototype);
var ub = Button.prototype;
ub.constructor = Button; // correct the constructor property
// instance methods
ub.hide = function () {
this._$container.hide();
};
ub.show = function () {
this._$container.show();
};
ub.disable = function () {
this._toggle(this._$btn, false);
};
ub.enable = function () {
this._toggle(this._$btn, true);
};
/*
* Grand-child class, concrete class
*/
AddCommentBtn.prototype = Object.create(Button.prototype);
var ap = AddCommentBtn.prototype;
ap.constructor = AddCommentBtn;
ap._onClick = function () {
this.hide();
this._expandedSection.showCommentTextInput();
};
ap.freeze = function () {
this._$btn.toggleClass("disabled", true);
this._disabled = true;
};
ap.unfreeze = function () {
this._$btn.toggleClass("disabled", false);
this._disabled = false;
};
ES6
class PageElement {
constructor() {
this._$loadingIndicator = null;
this._disabled = false;
}
_showLoading($element) {
this._$loadingIndicator = IU.addWaitingIndicatorToElement($element);
return this._$loadingIndicator;
}
_createIndicator(id) {
this._$loadingIndicator = IU.createWaitingIndicator(id);
return this._$loadingIndicator;
}
_hideLoading() {
if (this._$loadingIndicator) {
IU.removeIndicator(this._$loadingIndicator);
}
}
_toggle($element, state) {
$element.prop("disabled", !state);
}
}
class Button extends PageElement {
constructor(selector, container) {
super();
this._selector = selector; // fields
this._$container = container;
this._$btn = this._$container.find(this._selector);
}
hide() {
this._$container.hide();
}
show() {
this._$container.show();
}
disable() {
this._toggle(this._$btn, false);
}
enable() {
this._toggle(this._$btn, true);
}
}
class AddCommentBtn extends Button {
_onClick() {
this.hide();
this._expandedSection.showCommentTextInput();
}
freeze() {
this._$btn.toggleClass("disabled", true);
this._disabled = true;
}
unfreeze() {
this._$btn.toggleClass("disabled", false);
this._disabled = false;
}
}
Iterable
- Iterator: has a
next
method, which returns aniteratorResult
object with two propertiesvalue
anddone
- Iterable: has a method with
Symbol.iterator
as the key - All iterators created by generators are also iterables
- Three types in TypeScript syntax
interface Iterable {
[Symbol.iterator](): Iterator;
}
interface Iterator {
next(): IteratorResult;
}
interface IteratorResult {
value: any;
done: boolean;
}
Generator
- Call it once and get the handle to operate upon it
- Generating iterables
let o = {};
o[Symbol.iterator] = function* () {
yield* [1, 2, 3, 4, 5];
};
for (let e of o) {
info(e);
}
ESM
-
ES6 Modules and How to Use Import and Export in JavaScript (opens in a new tab)
How to use
import
andexport
for ESM -
Native ECMAScript modules - the first overview (opens in a new tab)
Destructuring
-
Assign Variables from Objects
const user = { name: "John Doe", age: 34 }; const { name: userName, age: userAge } = user; // userName = 'John Doe', userAge = 34
-
Assign Variables from Nested Objects
const user = { johnDoe: { age: 34, email: "johnDoe@freeCodeCamp.com", }, }; const { johnDoe: { age, email }, } = user;
-
Assign Variables from Arrays
- In the order of array elements, unneeded elements omitted
const [a, b, , , c] = [1, 2, 3, 4, 5, 6]; console.log(a, b, c); // 1, 2, 5
- Swap variable values:
let a = 8; let b = 6; [b, a] = [a, b]; console.info(a, b); // 6, 8
- Use Rest Parameter
const [a, b, ...arr] = [1, 2, 3, 4, 5, 7]; console.log(a, b); // 1, 2 console.log(arr); // [3, 4, 5, 7]
-
Pass an Object as a Function's Parameters
// No Destructuring const profileUpdate = (profileData) => { const { name, age, nationality, location } = profileData; // do something with these variables }; // Destructuring const profileUpdate = ({ name, age, nationality, location }) => { /* do something with these fields */ };
Asynchronous Programming
Async/Await
API
Object
- Iterate over object keys
Object.assign
- Doesn't copy getters and setters, in which case use class constructor function instead for cloning object.
Array
array.sort()
- Algorithm of
array.sort()
is implementation dependent. compareFunction
if omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element.
- Algorithm of
array.splice()
array.splice(startIndex, [deleteCount])
, ifdeleteCount
is omitted, all elements starting fromstartIndex
will be deleted.- The method has side effects on the array, therefore indices of elements are subject to change after the method call.
string
-
convert to an array of characters
-
ES6
-
Spread
operator[...'hello']
-
Array.from()
Array.from('hello')
-
-
DOM
-
Retrieving text
-
Element.innerHTML
(opens in a new tab)The HTML or XML markup contained within the element, essentially the source code
-
HTMLElement.innerText
(opens in a new tab)The rendered text content of the node and its descendants, which contains formatting.
-
Node.textContent
(opens in a new tab)The text content of the node and its descendants
-