https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
Overview# JavaScript language:
has no concept of input or output designed to run as a scripting language in a host environmentmost common host environment is the browser but JavaScript interpreters can also be found in a huge list of other placesserver-side environments such as Node.js NoSQL databases like the open source Apache CouchDB Adobe Acrobat, Adobe Photoshop SVG images etc. up to the host environment to provide mechanisms for communicating with the outside world multi-paradigm dynamic language supports object-oriented programming with object prototypes, instead of classes supports functional programming — because they are objects, functions may be stored in variables and passed around like any other object Types# Number# Copy console . log ( 3 / 2 ) ;
console . log ( Math . floor ( 3 / 2 ) ) ;
isFinite ( 1 / 0 ) ;
isFinite ( - Infinity ) ;
isFinite ( NaN ) ;
Convert Number# Copy
parseInt ( '123' , 10 ) ;
parseInt ( '010' , 10 ) ;
parseInt ( '010' ) ;
parseInt ( '11' , 2 ) ;
+ '42' ;
+ '010' ;
+ '0x10' ;
NaN# A special value called NaN (short for "Not a Number") is returned if the string is non-numeric:
Copy parseInt ( 'hello' , 10 ) ;
NaN + 5 ;
Number . isNaN ( NaN ) ;
Number . isNaN ( 'hello' ) ;
Number . isNaN ( '1' ) ;
Number . isNaN ( undefined ) ;
Number . isNaN ( { } ) ;
Number . isNaN ( [ 1 ] )
Number . isNaN ( [ 1 , 2 ] )
But don’t test for NaN using the global isNaN() function, which has unintuitive behavior :
Copy isNaN ( 'hello' ) ;
isNaN ( '1' ) ;
isNaN ( undefined ) ;
isNaN ( { } ) ;
isNaN ( [ 1 ] )
isNaN ( [ 1 , 2 ] )
String# Copy 'hello' . length ;
'hello' . charAt ( 0 ) ;
'hello, world' . replace ( 'world' , 'mars' ) ;
'hello' . toUpperCase ( ) ;
Boolean# false, 0, empty strings (""), NaN, null, and undefined all become false. All other values become true. Copy Boolean ( '' ) ;
Boolean ( 234 ) ;
Other types# null
: a value that indicates a deliberate non-value (and is only accessible through the null
keyword)undefined
: a value of type undefined
that indicates an uninitialized variable — that is, a value hasn't even been assigned yet. Variables# New variables in JavaScript are declared using one of three keywords: let
, const
, or var
.
let
allows you to declare block-level variables. The declared variable is available from the block it is enclosed in.
Copy
for ( let myLetVariable = 0 ; myLetVariable < 5 ; myLetVariable ++ ) {
}
const
allows you to declare variables whose values are never intended to change. The variable is available from the block it is declared in.
var
is the most common declarative keyword. It does not have the restrictions that the other two keywords have. A variable declared with the var keyword is available from the function it is declared in.
Copy
for ( var myVarVariable = 0 ; myVarVariable < 5 ; myVarVariable ++ ) {
}
In JavaScript, blocks do not have scope; only functions have a scope. So if a variable is defined using var
in a compound statement (for example inside an if control structure), it will be visible to the entire function. However, starting with ECMAScript 2015, let
and const
declarations allow you to create block-scoped variables.
If you declare a variable without assigning any value to it, its type is undefined
.
Operators# JavaScript's numeric operators are +
, -
, *
, /
and %
which is the remainder operator.
Values are assigned using =
.
Compound assignment using +=
, -=
etc..
Increment and decrement ++
and --
.
String concatenation +
.
Copy
'' + 4 ;
'3' + 4 + 5 ;
3 + 4 + '5' ;
Comparisons: <
, >
, <=
, >=
.
Equality: ==
and ===
, !=
and !==
.
Copy 123 == '123' ;
1 == true ;
123 === '123' ;
1 === true ;
Control structures# Copy var name = 'kittens' ;
if ( name === 'puppies' ) {
name += ' woof' ;
} else if ( name === 'kittens' ) {
name += ' meow' ;
} else {
name += '!' ;
}
name === 'kittens meow' ;
while ( true ) {
}
var input ;
do {
input = get_input ( ) ;
} while ( inputIsNotValid ( input ) ) ;
for ( var i = 0 ; i < 5 ; i ++ ) {
}
for...of# Copy const array1 = [ 'a' , 'b' , 'c' ] ;
for ( const element of array1 ) {
console . log ( element ) ;
}
for...in# Copy const object = { a : 1 , b : 2 , c : 3 } ;
for ( const property in object ) {
console . log ( ` ${ property } : ${ object [ property ] } ` ) ;
}
Logic# The &&
and ||
operators use short-circuit logic.
Copy
var name = o && o . getName ( ) ;
var name = cachedName || ( cachedName = getName ( ) ) ;
Ternary operator# Copy var allowed = ( age > 18 ) ? 'yes' : 'no' ;
switch# Copy switch ( action ) {
case 'draw' :
drawIt ( ) ;
break ;
case 'eat' :
eatIt ( ) ;
break ;
default :
doNothing ( ) ;
}
switch ( a ) {
case 1 :
case 2 :
eatIt ( ) ;
break ;
default :
doNothing ( ) ;
}
Objects# JavaScript objects can be thought of as simple collections of name-value pairs.
There are two basic ways to create an empty object:
var obj = new Object();
And:
var obj = {};
The second is called object literal syntax and is more convenient. This syntax is also the core of JSON format and should be preferred at all times.
Copy var obj = {
name : 'Carrot' ,
_for : 'Max' ,
details : {
color : 'orange' ,
size : 12
}
} ;
obj . details . color ;
obj [ 'details' ] [ 'size' ] ;
The following example creates an object prototype(Person
) and an instance of that prototype(you
).
Copy function Person ( name , age ) {
this . name = name ;
this . age = age ;
}
var you = new Person ( 'You' , 24 ) ;
obj . name = 'Simon' ;
var name = obj . name ;
obj [ 'name' ] = 'Simon' ;
var name = obj [ 'name' ] ;
var user = prompt ( 'what is your key?' )
obj [ user ] = prompt ( 'what is its value?' )
Arrays# Copy var a = new Array ( ) ;
a [ 0 ] = 'dog' ;
a [ 1 ] = 'cat' ;
a [ 2 ] = 'hen' ;
a . length ;
var a = [ 'dog' , 'cat' , 'hen' ] ;
a . length ;
var a = [ 'dog' , 'cat' , 'hen' ] ;
a [ 100 ] = 'fox' ;
a . length ;
typeof a [ 90 ] ;
a . push ( item ) ;
Iterate# Copy for ( var i = 0 ; i < a . length ; i ++ ) {
}
for ( const currentValue of a ) {
}
[ 'dog' , 'cat' , 'hen' ] . forEach ( function ( currentValue , index , array ) {
} ) ;
Method name Description a.toString()
Returns a string with the toString()
of each element separated by commas. a.toLocaleString()
Returns a string with the toLocaleString()
of each element separated by commas. a.concat(item1[, item2[, ...[, itemN]]])
Returns a new array with the items added on to it. a.join(sep)
Converts the array to a string — with values delimited by the sep
param a.pop()
Removes and returns the last item. a.push(item1, ..., itemN)
Appends items to the end of the array. a.shift()
Removes and returns the first item. a.unshift(item1[, item2[, ...[, itemN]]])
Prepends items to the start of the array. a.slice(start[, end])
Returns a sub-array. a.sort([cmpfn])
Takes an optional comparison function. a.splice(start, delcount[, item1[, ...[, itemN]]])
Lets you modify an array by deleting a section and replacing it with more items. a.reverse()
Reverses the array.
Functions# Copy function add ( x , y ) {
var total = x + y ;
return total ;
}
If no return statement is used (or an empty return with no value), JavaScript returns undefined
.
You can call a function without passing the parameters it expects, in which case they will be set to undefined
.
Functions have access to an additional variable inside their body called arguments, which is an array-like object holding all of the values passed to the function.
Copy function avg ( ) {
var sum = 0 ;
for ( var i = 0 , j = arguments . length ; i < j ; i ++ ) {
sum += arguments [ i ] ;
}
return sum / arguments . length ;
}
avg ( 2 , 3 , 4 , 5 ) ;
Rest parameters# Copy function avg ( ... args ) {
var sum = 0 ;
for ( let value of args ) {
sum += value ;
}
return sum / args . length ;
}
avg ( 2 , 3 , 4 , 5 ) ;
avg . apply ( null , [ 2 , 3 , 4 , 5 ] ) ;
avg ( ... numbers )
Anonymous functions# Copy var avg = function ( ) {
var sum = 0 ;
for ( var i = 0 , j = arguments . length ; i < j ; i ++ ) {
sum += arguments [ i ] ;
}
return sum / arguments . length ;
} ;
Recursive functions# Copy function countChars ( elm ) {
if ( elm . nodeType == 3 ) {
return elm . nodeValue . length ;
}
var count = 0 ;
for ( var i = 0 , child ; child = elm . childNodes [ i ] ; i ++ ) {
count += countChars ( child ) ;
}
return count ;
}
Arrow function# Copy
function ( a ) {
return a + 100 ;
}
( a ) => {
return a + 100 ;
}
( a ) => a + 100 ;
a => a + 100 ;
If you have multiple arguments or no arguments:
Copy
function ( a , b ) {
return a + b + 100 ;
}
( a , b ) => a + b + 100 ;
let a = 4 ;
let b = 2 ;
function ( ) {
return a + b + 100 ;
}
let a = 4 ;
let b = 2 ;
( ) => a + b + 100 ;
If the body requires additional lines of processing:
Copy
function ( a , b ) {
let chuck = 42 ;
return a + b + chuck ;
}
( a , b ) => {
let chuck = 42 ;
return a + b + chuck ;
}
Named functions:
Copy
function bob ( a ) {
return a + 100 ;
}
let bob = a => a + 100 ;
Used as methods# Copy var obj = {
i : 10 ,
b : ( ) => console . log ( this . i , this ) ,
c : function ( ) {
console . log ( this . i , this ) ;
}
}
obj . b ( ) ;
obj . c ( ) ;
Custom objects# Version 1
Copy function makePerson ( first , last ) {
return {
first : first ,
last : last
} ;
}
function personFullName ( person ) {
return person . first + ' ' + person . last ;
}
function personFullNameReversed ( person ) {
return person . last + ', ' + person . first ;
}
var s = makePerson ( 'Simon' , 'Willison' ) ;
personFullName ( s ) ;
personFullNameReversed ( s ) ;
Version 2
Copy function makePerson ( first , last ) {
return {
first : first ,
last : last ,
fullName : function ( ) {
return this . first + ' ' + this . last ;
} ,
fullNameReversed : function ( ) {
return this . last + ', ' + this . first ;
}
} ;
}
var s = makePerson ( 'Simon' , 'Willison' ) ;
s . fullName ( ) ;
s . fullNameReversed ( ) ;
Version 3
Copy function Person ( first , last ) {
this . first = first ;
this . last = last ;
this . fullName = function ( ) {
return this . first + ' ' + this . last ;
} ;
this . fullNameReversed = function ( ) {
return this . last + ', ' + this . first ;
} ;
}
var s = new Person ( 'Simon' , 'Willison' ) ;
Version 4
Copy function personFullName ( ) {
return this . first + ' ' + this . last ;
}
function personFullNameReversed ( ) {
return this . last + ', ' + this . first ;
}
function Person ( first , last ) {
this . first = first ;
this . last = last ;
this . fullName = personFullName ;
this . fullNameReversed = personFullNameReversed ;
}
Version 5
Copy function Person ( first , last ) {
this . first = first ;
this . last = last ;
}
Person . prototype . fullName = function ( ) {
return this . first + ' ' + this . last ;
} ;
Person . prototype . fullNameReversed = function ( ) {
return this . last + ', ' + this . first ;
} ;
var s = new Person ( 'Simon' , 'Willison' ) ;
s . toString ( ) ;
Person . prototype . toString = function ( ) {
return '<Person: ' + this . fullName ( ) + '>' ;
}
s . toString ( ) ;
Inner functions# Nested functions in JavaScript can access variables in their parent function's scope:
Copy function parentFunc ( ) {
var a = 1 ;
function nestedFunc ( ) {
var b = 4 ;
return a + b ;
}
return nestedFunc ( ) ;
}
Closures# A closure is a pairing of:
A function, and A reference to that function's outer scope (lexical environment) In the following code, inner
forms a closure with the lexical environment of the execution context created when foo
is invoked, closing over variable secret
:
Copy function foo ( ) {
const secret = Math . trunc ( Math . random ( ) * 100 )
return function inner ( ) {
console . log ( ` The secret number is ${ secret } . ` )
}
}
const f = foo ( )
f ( )
In other words: in JavaScript, functions carry a reference to a private "box of state", to which only they (and any other functions declared within the same lexical environment) have access. This box of the state is invisible to the caller of the function, delivering an excellent mechanism for data-hiding and encapsulation.
Uses of Closures# Closures are useful whenever you need a private state associated with a function.
Private Instance Variables# In the following code, the function toString
closes over the details of the car.
Copy function Car ( manufacturer , model , year , color ) {
return {
toString ( ) {
return ` ${ manufacturer } ${ model } ( ${ year } , ${ color } ) `
}
}
}
const car = new Car ( 'Aston Martin' , 'V8 Vantage' , '2012' , 'Quantum Silver' )
console . log ( car . toString ( ) )
Functional Programming# In the following code, the function inner
closes over both fn
and args
.
Copy function curry ( fn ) {
const args = [ ]
return function inner ( arg ) {
if ( args . length === fn . length ) return fn ( ... args )
args . push ( arg )
return inner
}
}
function add ( a , b ) {
return a + b
}
const curriedAdd = curry ( add )
console . log ( curriedAdd ( 2 ) ( 3 ) ( ) )
Classes# Class declarations# Copy class Rectangle {
constructor ( height , width ) {
this . height = height ;
this . width = width ;
}
}
Class expressions# Copy
let Rectangle = class {
constructor ( height , width ) {
this . height = height ;
this . width = width ;
}
} ;
console . log ( Rectangle . name ) ;
let Rectangle = class Rectangle2 {
constructor ( height , width ) {
this . height = height ;
this . width = width ;
}
} ;
console . log ( Rectangle . name ) ;