匿名函数和闭包这两个概念,经常混用。 闭包是指有权访问另一个函数作用域中的变量的函数。
function sortFunction(prototypeName){ return function(obj1,obj2){ var value1 = obj1[prototypeName]; var value2 = obj1[prototypeName]; if (value1 > value2) { return 1; }else if(value1 < value2){ return -1; }else{ return 0; } }; }
突出的那两行代码是内部函数(一个匿名函数)中的代码,这两行代码访问了外部函数中的变量 propertyName。即使这个内部函数被返回了,而且是在其他地方被调用了,但它仍然可
以访问变量 propertyName。之所以还能够访问这个变量,是因为内部函数的作用域链中包含sortFunction()的作用域。
当某个函数被调用时,会创建一个执行环境(execution context)及相应的作用域链。
function compare(value1,value2){ if (value1 > value2) { return 1; }else if(value1 < value2){ return -1; }else{ return 0; } }
var result = compare(5,10);
在创建 compare()函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的[[Scope]]属性中。
当调用 compare()函数时,会为函数创建一个执行环境,然后通过复制函数的[[Scope]]属性中的对象构建起执行环境的作用域链。
闭包的理解(函数的作用域链)
这个算是闭包的原理吧:
在JS中对函数进行调用时,会为每个函数增加一个scope属性,通过这个属性指向一块内存,这块内存包含所有的上下文使用的变量,在函数中调用了新函数时,调用的新函数依然有一个作用域来指向原有函数的SCOPE和自己新增加的SCOPE,这样就形成了
一个链式结构,这就是JS的作用域链。
因为函数都是在全局对象中,所以顶端就是全局的作用域链。
var color = "red"; function showColor(){ return this.color; } function changeColor(){ var another = "blue"; function swapColor(){ var swap = another; another = color; color = swap; } swapColor(); } changeColor(); showColor(); //blue
图解如下:
一个例子:
使用闭包虽然可以扩大作用域,但是消耗更大的内存,所以尽量少使用。