- false
- null
- undefined
- empty string ''
- number 0
- NaN All other values are truthy including true, 'false', and all objects
A compilation unit contains a set of executable statements. In browsers, each <script>
tag delivers a compilation unit that is immediately executed inline.
A block is a set of statements wrapped in curly braces. Blocks in JS do not create a new scope, so variables should be defined at the top of the function.
-
if (expression) { block } else { block }
-
switch (expression) { case clause: statements; default: statements }
-
while (expression) { block }
-
for (var i = 0; i < 10; i++ ) { block }
-
for in - enumerates property names (keys) of an object. Property name is assigned to variable on each iteration.
for (myvar in obj) {
if (obj.hasOwnProperty(myvar)) {
...
}
}
-
do { block } while (expression);
-
try executes a block and catches exceptions thrown by the block try {block} catch (variable)
-
throw expression; - raises an exception. expression is usually an object literal
-
return expression; - early return from a function.
-
break label; - early exit from a loop or switch
The simplest expressions are literal values (strings, numbers), variables, built-in values (true, false, null, undefined, NaN, Infinity), invocation expression preceded by new, expressions wrapped in parentheses, ternary operators.
-
Ternary: Takes three operands (operand) ? truthy value : falsy value
-
typeof: determines if a variable is number, string, boolean, undefined, function or object
-
!: negation operator
-
+: concatenation
-
&&: produces value of first operand if falsy, otherwise second operand
-
||: produces the value of the first operand if truhty, othereise second operand
Object literals are a convenient notation for specifying new objects. The names of properties can be names or strings.
Function literal defines a function value. It can have an option name that can be used to call itself recursively.
- The simple types of JS are numbers, strings, booleans, null and undefined. All other values are objects.
- Numbers, string and booleans are object-like in that they have methods, but they are immutable.
- Objects in JS are mutable keyed collections.
- Arrays are objects, Functions are objects, Regular expressions are objects, Objects are objects
- Objects are containers of properties, where a property has a name and value.
- Objects are class-free.
- Objects can contain other objects -- useful for representing tree structures
- JS includes prototype linkage that allows objects to inherit properties of other objects.
Provide a very convenient notation for creating new objects.
var stooge = {
"first-name": "Jerome",
"last-name": "Howard"
};
/* quotes are optional around propert names if the name would be a legal variable name */
var flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: {
IATA: "LAX",
time: "2004-09-23 10:42",
city: "Los Angeles"
}
};
Values can be retrieved using Array-style syntax or dot notation (if property name is a legal javascript name).
stooge["first-name"]; // "Jerome"
flight.departure.IATA. // "SYD"
stooge["middle-name"]; // undefined
var middle = flight.status || "unknown"; // middle = "unknown"
stooge["first-name"] = "Jerome"; // object is updated
stooge.nickname = "Curly"; // object is augmented with new property
stooge["middle-name] = "Curly" // object is augmented with new property
Objects are passed around by reference. They are never copied
var x = stooge;
x.nickname = 'Curly';
var nick = stooge.nickname;
// nick is 'Curly' because x and stooge are references to same object
- Every object is linked to a prototype object.
- All objects are linked to Object.prototype.
- When you make a new object, you can select the object that should be its prototype.
// Cleaner solution to object creation
// this augments the main Object with a *create* method
if (typeof Object.create !== 'function') {
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
}
var another_stooge = Object.create(stooge);
-
The prototype link is used only in retrieval. If an object lacks a property name, JS searches up the prototype chain until it reaches Object.prototype. If the desired property does not exist anywhere in the prototype chain the result is undefined. This is called delegation.
-
Prototype relationship is dynamic. If you add a new property to a prototype, it is instantly visible to all objects based on that prototype:
stooge.profession = 'actor'; another_stooge.profession // 'actor'
JS supports the abilty to inspect objects to determine what properties is has. The typeof
operator is used.
typeof flight.number // 'number'
typeof flight.status // 'string'
typeof flight.arrival // 'object'
// any property on prototype chain cna produce a vlaue
typeof flight.toString // 'function'
flight.hasOwnProperty('toString') // false
The for in
statement loops over all of the property names in an object -- including functions and properties in the prototype.
// filter out prototype properties
var name;
for (name in another_stooge) {
if (typepf another_stooge[name] !== 'function') {
console.log(name + ': ' + another_stooge[name]);
}
}
Remove a property from an object
delete another_stooge.nickname;
- Functions are the fundamental modular unit in JS.
- Functions in JS are objects.
- Functions are linked to Function.prototype which is linked to Object.prototype.
- Functions have two hidden properties (context and code)
- Every function object is created with a prototype property.
- The prototype property value is an object with a
constructor
property. - Functions can be stored in variables, objects and arrays (since they are objects).
- Functions can be invoked.
- Function objects are created with function literals.
- Variables hold the function objects.
- A function literal can appear anywhere an expression can appear even inside other functions.
- Inner functions have access to parameters and variables of the function it is nested within.
- The function object created by a function literal contains a link to the outer object -- this is called a closure
var add = function (a,b) {
return a + b;
};
- Invoking a function suspends the current function and passes control and parameters to the new function.
- Every function receives two additional parameters automatically (
this
andarguments
) - The invocation operator is a pair of parenthesis that follow any expression that produces a function value.
- When a function is stored as a property of an object it is called a method.
- When a method is invoked,
this
is bound to that object. - If an invocation contains a refinement (dot or []) expression it is invoked as a method.
var myObject = {
value: 0,
increment: function (inc) {
this.value += typeof inc === 'number' ? inc : 1;
}
};
myObject.increment();
console.log(myObject.value);
myObject.increment(2);
console.log(myObject.value);
A method can use this
to access the object to modify or retrieve values. The binding of this
happens at invocation time. Late binding makes functions highly reusable.
When a function is not a property of an object, it is invoked as a function. this
is bound to the global object (bad).
var sum = add(3,4);
Fix
If a method defines and assigns a variable to this
, the inner function will have access to this
through that variable. The convention is to use that
for the variable name.
myObject.double = function() {
var that = this; // workaround
var helper = function() {
that.value = add(that.value, that.value);
};
helper();
};
// Invoke double as a method
myObject.double();
console.log(myObject.value);
- JS is a prototypal inheritance language - objects inherit directly from other objects.
- JS offers an object-making syntax similar to classical languages using the
new
prefix. - Functions invoked with
new
create new objects with hidden link to the prototype member of the function andthis
bound to the new object.
- All functions receive a bonus array-like parameter
arguments
when they are invoked. - Provides access to all arguments supplied (even extraneous) with invocation.
- You can use
arguments
to write functions with unspecified number of parameters
var sum = function() {
var i, sum=0;
for (i=0; i<arguments.length; i+=1) {
sum += arguments[i];
}
return sum;
};
console.log(sum(2,4,6,8,10,12));
Return causes the function to return early. If a return value is not specified, then undefined is returned.
When errors occur that interfere with normal flow and exeption can be thrown.
var add = function (a,b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw {
name: 'TypeError',
message: 'add requires numbers'
};
}
return a + b;
};
throw
should be given an exception object withname
andmessage
properties.- Exception objects are delivered to the
catch
clause of atry
statement
var try_it = function() {
try {
add("seven");
} catch (e) {
console.log(e.name + ': ' + e.message);
}
};
try_it();
- JS allows basic types to be augmented. This includes objects, functions, arrays, strings, numbers, regex, and booleans.
// make a method available to all functions
Function.prototype.method = function(name, func) {
if (!this.prototype[name]) {
this.prototype[name] = func;
return this;
}
};
// makes adding new methods to a prototype cleaner
Number.method('integer', function() {
return Math[this < 0 ? 'ceil' : 'floor'](this); // Math.ceil(this)
});
console.log( (-10/3).integer() );
// add a trim method to all strings
String.method('trim', function() {
return this.replace(/^\s+|\s+$/g, '');
});
console.log(' trim me '.trim());
Recursive functions call themselves. Recursion allows dividing a problem into a set of smaller subproblems.
- JS does not have block scope.
- JS has function scope -- params and vars defined in a function are not visible outside the function.
- In JS it is best to declare vars used in a function at the top of the function body.
- Inner functions get access to the params and vars of the functions they are defined within.
// use a closure to protect the value from changes
var myObject = function() {
var value = 0;
// return an object with an increment function -- closure
return {
increment: function (inc) {
value += typeof inc === 'number' ? inc : 1;
},
getValue: function() {
return value;
}
};
}();
- myObject is assigned the result of invoking a function -- not an actual function.
- the function returns an object containing two methods that have special access to the value variable.
// define a quo function with a private `status` property
// returns an object with a get_status method
var quo = function(status) {
return {
get_status: function() {
return status;
}
};
}
var myQuo = quo("amazed"); // myQuo has a reference to object with get_status method
// myQuo.get_status() method has access to quo's status property even though quo
// already returned
console.log(myQuo.get_status());