This is an adaptation of what you'd find in john resig's Learning Advanced Javascript app.
var math = {
fact: function fact(n){
return n > 0 ? n * fact(n-1): 1;
},
fact1: function (n) {
return n > 0? n * math.fact1(n-1) : 1;
}
};
console.log(math.fact(5)); // 120
console.log(math.fact1(5)); // 120
var o = {
x: math.fact,
y: math.fact1
};
math = {};
console.log(o.x === undefined); // false
console.log(o.y === undefined); // false
console.log(o.x(5)); // 120
console.log(o.y(5)); // Uncaught TypeError: math.fact1 is not a function
One would expect o.x(5)
should throw an error, but it executes. Why?
When an object literal expression is evaluated, the expression to the right of each colon is evaluated and assigned to the specified property.
So when this executes:
var o = {
x: math.fact,
y: math.fact1
};
the expression math.fact
is evaluated, and the result is the function that math.fact
is referring to at that time.
The same goes for math.fact1
.
So even if you reassign the math
variable with math = {}
. o.x
will continue to refer to that function. The o
object has no knowledge of the math
variable.
o.y(5)
throws an error has to do with closures.
o.y
refers to this function:
function (n) {
return n > 0? n * math.fact1(n-1) : 1;
}
You can see here that it uses the math
variable. Even if you reassign the math
variable, this function will continue to refer to the variable itself.
When you call o.y(5)
, the function executes, but when it tries to call math.fact(n-1)
, that fails, because math
no longer has a property called fact
.
o.x
does not have the problem that o.y
has. It is a named function, and therefore is able to continue to call itself even after math
is reassigned.