Marek Matczak
...has nothing common with Java * except for some key words
...is more like “Lisp in C's clothing”
*Douglas Crockford
...has objects, but is class-free
...is of single-threaded nature
...has asynchronous programming model
...is object oriented and functional at the same time
Always use var to declare variables
If you don't, they become global variables
Variable declarations get hoisted to the top of a function...
...which may be confusing:
var myVar = 'global';
var myFunction = function () {
console.log(myVar); // undefined
var myVar = 'local';
console.log(myVar); // 'local'
};
myFunction();
The above code behaves as if it looked like this:
var myVar = 'global';
var myFunction = function () {
var myVar;
console.log(myVar); // undefined
myVar = 'local';
console.log(myVar); // 'local'
};
myFunction();
Eliminates logical errors caused by hoisting
var a = 1,
b = 2,
sum = a + b,
myVar,
hello = function () {
return 'Hello!';
};
can be created in a very convenient way with object literals:
var emptyObject = {},
person = {
firstName : 'John',
lastName : 'Example',
age : 30
};
Values' retrieval
var person = {
firstName : 'John',
lastName : 'Example',
age : 30
}, salutation, street;
// retrieval
person.firstName // 'John'
person['lastName'] // 'Example'
person.salutation // undefined
salutation = person.salutation || ''; // the default operator
person.address.street // throws TypeError
street = person.address && person.address.street // undefined
Values' update and properties' removal
var person = {
firstName : 'John',
lastName : 'Example',
age : 30
}, salutation, street;
// update
person['firstName'] = 'Joe';
person.age = 33;
// delete
delete person.age;
are objects
can be created with function literals:
var add = function (a, b) {
return a + b;
};
add(1, 2); // 3
stored as properties of objects...
var person = {
firstName : 'John',
lastName : 'Example',
age : 30,
letMeIntroduceMyself : function () {
return 'My name is ' + this.firstName + ' ' + this.lastName;
}
};
person.letMeIntroduceMyself(); // My name is John Example
person.firstName // 'John' - no privacy
...are called methods:
is defined by functions, and no {} blocks
var myFun = function (someInput) {
var a = 1, b = 2,
yourFun = function () {
var b = 22, c = 3;
// at this point a = 1, b = 22, c = 3
a = 11;
};
// at this point a = 1, b = 2, c is not defined
yourFun();
// at this point a = 11, b = 2, c is not defined
};
myFun();
enables a function to keep its creation context
var myObjectFactory = function (param) {
var value = 'Value';
return {
theseAreMySecrets : function () {
return 'value = ' + value + ', param = ' + param;
}
};
},
myObject = myObjectFactory('Param');
myObject.theseAreMySecrets(); // value = Value, param = Param
myObject.value; // undefined
...even if its lifetime is shorter than the function's one
makes use of function scope and closure
var person = (function () {
var details = {
firstName : 'John',
lastName : 'Example',
age : 30
};
return {
letMeIntroduceMyself : function () {
return 'My name is ' +
details.firstName + ' ' + details.lastName;
}
};
})();
person.letMeIntroduceMyself(); // My name is John Example
person.details; // undefined
is widely used for programming services in
is intended to be invoked with the new prefix (forgetting it makes this bound to the global object!)
creates a new object with a hidden link to its prototype
is kept in a variable with a capitalized name by convention
var Person = function () {
this.firstName = 'John';
this.lastName = 'Example';
this.age = 30;
}, johnExample;
Person.prototype.letMeIntroduceMyself = function () {
return 'My name is ' + this.firstName + ' ' + this.lastName;
};
johnExample = new Person();
johnExample.letMeIntroduceMyself(); // My name is John Example
johnExample.firstName; // 'John' - no privacy
is used for defining controllers in
var create = function (from) { // added to ECMAScript 5 as Object.create
var F = function () {};
F.prototype = from;
return new F();
},
parent = {
firstName : 'John',
lastName : 'Example',
letMeIntroduceMyself : function () {
return 'My name is ' + this.firstName + ' ' + this.lastName;
}
}, child;
child = create(parent);
child.firstName = 'Joe';
parent.letMeIntroduceMyself(); // My name is John Example
child.letMeIntroduceMyself(); // My name is Joe Example
In scopes prototypically inherit from each other
var parent = function (my) {
var that = {},
details = {
firstName : 'John',
lastName : 'Example',
};
my = my || {}; // keeps secrets shared in the inheritance chain
my.details = details; // makes details shared by descendants
that.letMeIntroduceMyself = function () {
return 'My name is ' + details.firstName + ' ' + details.lastName;
};
return that;
},
child = function(name) {
var my = {},
that = parent(my);
my.details.firstName = name;
return that;
};
johnExample = parent();
joeExample = child('Joe');
johnExample.letMeIntroduceMyself(); // My name is John Example
joeExample.letMeIntroduceMyself(); // My name is Joe Example
joeExample.firstName; // undefined