- sources: MDN, google/airbnb style guides
/// a one line comment
/* a mutli-
line comment
/*
var
declare a variable, can optionally initialize (assign) a value
var x = 42
: declare local or global variables
x = 42
: declare a global variable (bad)
let
declare a block scope variable, can optionally initialize it a value
let y = 13
: declare a block scope variable
cont
declare a read-only constant
Note: a var
statement without initial assignment gives the specified
identifier a value of undefined
(attempts to access it result in undefined
)
Note: attempts to access undeclared variables result in ReferenceError
undefined
behaves asfalse
when used in a boolean contextundefined
behaves asNaN
when used in a numeric context- a
null
variable behaves as false in a boolean context and 0 in a numeric context
-
using
var
outside of any function declares a global variable (available to any code in the current document) -
using
var
within a function declares a local variable (available only within that function) -
ES5: does not have block statement scope
-
ES5: a variable declared within a block is local to the function/global scope that contains that block
e.g.
// ES5
if (true) {
var x = 5;
}
console.log(x); // ES5: x is 5 (x is global since block is in global scope)
// ES6
if (true) {
let y = 5;
}
console.log(x); // ES6: y is undefined (ReferenceError) (y is within block-level scope)
-
hoisting: variables are hoisted or lifted to the top of the function/statement (you can refer to a variable declared further down in the document without getting an exception)
-
hoisted variables return a value of undefined
e.g.
// Example 1
console.log(x === undefined); // true
var x = 3;
// Example 2
// if referenced here, myvar would return a value of undefined
var myvar "my value";
(function() {
console.log(myvar); //undefined
var myvar = "local value";
})
- best practice: all
var
statements should be placed as far towards the top of a function as possible
Note: ES6's let (const)
will not hoist variable to top of a block
(referencing before declaration causes a ReferenceError
(variable in a
'temporal dead zone at beginning of block until the declaration')
// ES6
console.log(x); // ReferenceError
let x = 3;
- only function declarations get hoisted, function expressions
// function declaration - is hoisted
foo(); // "bar"
function foo() {
console.log("bar");
}
// function expression - not hoisted
baz(); // TypeError: baz is not a function
var baz = function() {
console.log("bar2");
}
- globals are properties of the global object (in browsers, the
window
)
const
: create read-only constant, must be initialized- scope is same as
let
block scope variables - can't be the same name as a function or variable in same scope
- Boolean,
true
andfalse
- null, a special keyboard denoting null value
- undefined, top-level property with undefined value
- Number,
42
or3.14159
- String, "i'm a string"
- Symbol, (New in ES6) - a data type with unique and immutable instances
Other fundamental elements:
-
Objects
(named containers for values) -
functions
(procedures that your app can execute)
-
JavaScript is dynamically typed (no specification of data type of a variable needed at declaration)
-
data types are converted automatically as needed during script execution
// numeric + string values --> numberic values converted to string
x = "The answer is " + 42 // "The answer is 42"
e.g.:
// numeric + string values --> numberic values converted to string
x = "The answer is " + 42 // "The answer is 42"
// numbers are not converted to strings when using operators other than `+`
// (strings are converted to numbers)
"37" - 7 // 30
"37" + 7 // "377"
parseInt()
- only returns whole numbers (can't use for decimals), best practice: include radix parameter to indicate which numerical system to useparseFloat()
// unary plus can be used to retrive a number from a string
'1.1' + '1.1' // '1.11.1'
(+'1.1') + (+'1.1') // 2.2 (parens not required)
- literals are used to represent values, they are fixed (not variables), that you literally provide
- array literals are
Array
objects - array literal: 0 or more expressions, each of which is an array element,
enclosed in square brackets (
[]
) - creating an array literal - the array is initialized with the specified values, length = # of arguments specified
- Note: an array literal is a type of object initializer
- an array literal in a top-level script = JS re-interprets the array during each evaluation of its containing expression
- a literal within a function is created on each function call
var coffee = ['French Roast', 'Colombian', 'Kona'];
- not necessary to specify all elements in an array literal, two commas in a
row will result in
undefined
between themvar fish = ['lion', , 'angel']; // ['lion', undefined , 'angel']
- Note: trailing comma is ignored (best practice: don't use, can cause problems
in older browsers)
var myList = ['home', , 'school']; // length of myList is 3, no myList[3] exists var myLis = [ , 'Home', , 'school']; // length is 4, myList[0]/myList[2] are `undefined`
- best practice: use
undefined
explicitly in array literals to mark missing elements
- Boolean literal values:
true
andfalse
(not the same as the identically- named primitive values of the Boolean object (Boolean object is a wrapper around the primitive Boolean data type))
- decimal integer, no leading 0
- octal, leading zero, 0-7
- hexadecimal, leading 0x, 0-9 and a-f
- binary, leading 0b, 0 or 1
floating-point literals can consist of:
- a decimal integer (can be signed -/+)
- a decimal point (".")
- a fraction (another decimal number)
- an exponent (an e/E followed by an int, can be signed -/+)
- object literal: list of 0 or more pairs of property names and associated values, enclosed in
{}
var sales = "Toyota";
function carTypes(name) {
if (name === "Honda") {
return name;
} else {
return "Sorry, we don't sell " + name + ".";
}
}
var car = { myCar: "Saturn", getCar: carTypes("Honda"), special: sales };
console.log(car.myCar); // Saturn
console.log(car.getCar); // Saturn
console.log(car.special); // Toyota
- can use numeric or string literal for name of a property (can next an object inside another)
var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
console.log(car.manyCars.b); // Jeep
console.log(car[7]); Mazda
- object property names can be any string (including empty string)A
- properties that are not valid identifiers must be enclosed in quotes
- properties not valid identifiers cannot be accessed using a dot (
.
), can be using array-like notation (objectName[]
)
var unusualNames= {
"": "An empty string",
"!": "Bang!"
}
console.log(unusualNames.""); // SyntaxError: Unexpected string
console.log(unusualNames[""]); // An empty string
console.log(unusualNames.!); // SyntaxError: Unexpected token !
console.log(unusualNames[!]); // Bang!
- support setting prototype at construction
- shorthand for foo: foo assignments
- defining methods
- making super calls
- computing property names with expressions
- brings object literals and class declaration closer together
var obj = {
// __proto__
__proto__: theProtoObj
handler, // shortand for 'handler: handler'
// Methods
toString() {
return "d " + super.toString(); // Super call
},
[ 'prop_' + (() => 42)() ]: 42 // computed (dynamic property names)
}
Note:
var foo = {a: "alpha", 2: "two"};
console.log(foo.a); // alpha
console.log(foo[2]); // two
console.log(foo.2); // Error: missing ) after argument list
console.log(foo[a]); // Error: a is not defined
console.log(foo["a"]); // alpha
console.log(foo["2"]); // two
- pattern enclosed between slashes
var re = /ab+c/;
- 0 or more characters enclosed in double (
"
) or single quotes ('
) - can call any methods of the String object on a string literal value (JS auto-converts string literals to a temporary String object)
- use string literals unless you specifically need to use a String object
console.log("John's cat".length);
- template strings provide syntactic sugar for constructing strings
- similar to interpolation features in Python
`In JavaScript '\n' is a line-feed` // basic literal string creation
`In JavaScript this is
not legal` // multiline strings
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?` // String interpolation
// construct an HTTP request prefix is used to interpret the replacements and construction
POST`http://foo.org/bar?a=${a}&b=${b}
Content-Type: application/json
X-Credentials: ${credentials}
{ "foo": ${foo},
"bar": ${bar}}`(myOnReadyStateChangeHandler);
- special characters can be inserted using a backlash (
\
)
- un-special characters preceded by a backslash are ignored (deprecated, don't do this)
- can escape line breaks by preceding them with backslash
var str = "this string \
is broken \
across multiple\
lines."
console.log(str); // this string is broken across multiplelines
- no heredoc syntax, but can use
\n\
at end of each line
var x = 1;
{
var x = 2; // inside block statement
}
console.log(x); // outputs 2
- ES5: does not have block scope! Variables declared (
var
) within a block are scoped to the containing function or script, the effects of setting them persist beyond the block itself - ES6: the
let
variable declaration is block scoped
- best practice: always include block statements (
{}
), even if only one statement is used for a condition
if (condition_1) {
statement_1;
} else if (condition_2) {
statement_2;
} else if (condition_n) {
statemnt_n;
} else {
statement_last;
}
- best practice: assignment in a conditional expression is bad, if you need to, put additional parens around the assignment
if ((x = y)) {
// statements here
}
These all evaluate to false:
false
undefined
null
0
NaN
""
(the empty string)
-
everything else, including all objects, eval to
true
when passed to a conditional statement -
Note: don't consue primitive boolean values
true
/false
with the true/false values of theBoolean
object
var b = new Boolean(false);
if (b) // this condition is true
if (b == true) // this condition is false
switch (expression) {
case label_1:
statements_1
[break;]
case label_2:
statements_2
[break;]
...
default:
statements_def
[break;]
}