Data types
There are 7 primitive types in Javascript: string, number, bigint, boolean, symbol, null and undefined, while object is special.
| Data type | Internal represention |
|---|---|
string |
UTF-16 characters |
number |
IEEE-754 64-bit, equally double in C/C++ |
bigint |
Integer in ±253-1 |
boolean |
true/false |
symbol |
Unique identifier created from Symbol() |
null |
Empty or unknown value |
undefined |
Unassigned value |
object |
Keyed collections of various data |
🛈 null is used to represent absence of any object value, while undefined means “value is not assigned” and should not be used directly
Primitive are copied by value.
1 | let a = "Hello, World!"; |
object are copied “by reference”.
1 | let a = {user: "Alice", money: 1000}; |
🛈 typeof(x) can be used to find the type of argument x
Integer-string conversion
String concatenation with binary +
If any of the operands is a string, then the other one is converted to string.
1 | "1" + 2 // "12" |
The first + sums two numbers, so it returns 4, then the next + adds the string "2" to it.
1 | 2 + 2 + "2" // "42" and not "221", from left to right |
The first operand is a string, the compiler treats the other two operands as strings too. The 2 gets concatenated to ‘1’.
1 | "2" + 2 + 2 // "222" and not "24" |
The binary + is the only operator that supports strings in such a way. Other arithmetic operators work only with numbers and always convert their operands to numbers.
1 | 6 - "2" // 4, "2" is converted to number |
Numberic conversion with unary +
Unary + converts string to number
1 | +"1" // 1 |
⚠ "", null and undefined are special case in numberic conversion
| Expression | Result |
|---|---|
+"" |
0 |
+null |
0 |
+undefined |
NaN |
🛈 NaN represents an value that is undefined or unrepresentable, defined in IEEE 754
Boolean conversion
Values that are “empty”, like 0, an empty string, null, undefined, and NaN, become false, also called falsy value.
Otherwise, is true, also called truthy value
1 | Boolean("some") // true |
Comparison of different types
When comparing string to number, Javascript converts string to number
1 | "2" > 1 // 2 > 1, true |
The conditional logic in Javascript is just confused and erroneous.
Table 1: Truth Table
OR operator ||
|| operator finds the first truthy value, not just true/false.
If all falsy value, return the last value.
1 | false || true // true |
AND operator &&
&& operator finds the first falsy value, not just true/false.
If all trusy value, return the last value.
1 | false && true // false |
Both || and && have short-circuit evaluation. That is, these operators processes its arguments until the first truthy/falsy value is found, and then the value is returned immediately.
Double NOT operator !!
!! converts its operand to boolean.
Nullish coalescing operator ??
The result of a ?? b:
If a defined, not null or undefined, then a.
Otherwise, b.
1 | // Example 1 |
⚠ undefined ≠ not defined variable, variable must be declared before use.
(More content is coming soon…)
Optional chaining ?.
Object to primitive conversion
Backticks and formatted string
Unicode characters in string: Surrogate pairs
Array
Performance issues
Sorting
Iterable
Object as object key
Object only support string, number and symbol as key.
Use object as key becomes string key [object Object], while map can use any type as key.
WeakMap/WeapSet
Destructuring assignment, a.k.a structured binding
Date
Function
Normal function
1 | fucntion func(a, b) { |
Arrow fcuntion
Arrow function does not have this.
1 | let func = (a, b) => { |
Arrow function capture this as normal variable in the outer lexical environment. Different from normal function,
arrow function does not have this, arguments and super.
1 | let user = { |
⚠ Arrow function cannot run with new since it does not have this.
Lexical Environments
All functions remember the Lexical Environment in which they were made.
A Hidden [[Environment]] property stores a reference to the Lexical Environment. This object hold all variable and a reference to outer enviroment
Such variables in [[Environment]] will become unavailable in debugging.
Closure
Unbounded this
🛈 Arrow function does not have its own this, reference from outer this instead.
Rest parameters and spread syntax, a.k.a parameter pack
Rest parameters (Variable arguments)
1 | function func(arg1, arg2, ...last) { |
⚠ The rest parameters must be at the end.
🛈 A special array-like object arguments contains all arguments by their index for all function except arrow function.
Spread syntax (Argument expansion)
1 | let args = ["apple", "pinapple", "orange"] |
Function is object
Function is a normal callable object as same as other object.
Initial properties
| Argument | |
|---|---|
name |
Function name (get from assignement) |
length |
Number of arguments (Rest parameters are not counted) |
Function properties is not local variable
new Function syntax
Create function from string
1 | let func = new Function([arg1, arg2, ...argN], functionBody); |
Function created using new Function() does not inherit the lexical environment but the global one. Therefore, such function cannot access to outer variables.
Decoration and forwarding
Decorator is a wrapper around a function that alters its behavior.
There are two built-in functions call function with this = context and forward the arguments.
1 | func.call(context, arg1, arg2, ...) |
1 | func.apply(context, args) |
🛈 apply() accepts only array-like args while call() can pass arbitrary arguments.
🛈 apply() tends to be faster in most of the cases due to internal optimization.
Bind
bind() can be used to bind the function with this = context and set its arguments, resulting a callable object.
1 | bind(context, arg1, arg2, ...) |
🛈 Set context = null if no this.
Old var syntax
var declarion
Object
Object Property Flags
Object value has three property flags,writable: if true, the value can be changed, otherwise it’s read-only.enumerable: if true, then listed in loops, otherwise not listed.configurable: if true, the property can be deleted and these attributes can be modified, otherwise not.
🛈 Once a property is set configurable: false, all property flags cannot be changed again.
The default property flags for new property is all true.
Accessor property
Prototype
Old Way
F.__proto__
Modern way
F.prototype
Global object
| Environment | Name |
|---|---|
| browser | window |
| Node.js | global |
| Standard | globalThis |