deo*_*oll 0 javascript closures function function-expression
这是对你在john resig的Learning Advanced Javascript应用程序中找到的内容的改编.
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
Run Code Online (Sandbox Code Playgroud)
人们会期望o.x(5)应该抛出错误,但它会执行.为什么?
评估对象文字表达式时,将评估每个冒号右侧的表达式并将其分配给指定的属性.
所以当执行时:
var o = {
x: math.fact,
y: math.fact1
};
Run Code Online (Sandbox Code Playgroud)
表达math.fact进行评价,其结果是,功能math.fact指的是在那个时候.
同样的道理math.fact1.
所以即使你重新分配math变量math = {}.o.x将继续参考该功能.该o对象没有的知识math变量.
o.y(5)抛出错误
的原因与闭包有关.
o.y 指的是这个功能:
function (n) {
return n > 0? n * math.fact1(n-1) : 1;
}
Run Code Online (Sandbox Code Playgroud)
你可以在这里看到它使用math 变量.即使重新分配math变量,此函数也将继续引用变量本身.
当你调用时o.y(5),函数会执行,但是当它尝试调用math.fact(n-1)时,失败,因为math不再有一个被调用的属性fact.
o.x没有问题o.y.它是一个命名函数,因此即使在math重新分配后也能够继续调用它自己.