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:
the expression
math.fact
is evaluated, and the result is the function thatmath.fact
is referring to at that time.The same goes for
math.fact1
.So even if you reassign the
math
variable withmath = {}
.o.x
will continue to refer to that function. Theo
object has no knowledge of themath
variable.The reason why
o.y(5)
throws an error has to do with closures.o.y
refers to this function:You can see here that it uses the
math
variable. Even if you reassign themath
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 callmath.fact(n-1)
, that fails, becausemath
no longer has a property calledfact
.o.x
does not have the problem thato.y
has. It is a named function, and therefore is able to continue to call itself even aftermath
is reassigned.