闭包允许你引用存在于外部函数中的变量。然而,它并不是使用该变量创建时的值,相反,它使用外部函数中该变量最后的值。下面学步园小编来讲解下闭包有什么特性?
闭包有什么特性
我们先来看一个例子,如果不了解 JavaScript 的特性,很难找到原因:
var outter = [];
function clouseTest () {
var array = ["one", "two", "three", "four"];
for(var i = 0; i < array.length;i++){ var x = {}; x.no = i; x.text = array[i]; x.invoke = function(){ print(i); } outter.push(x); } } //调用这个函数 clouseTest(); print(outter[0].invoke()); print(outter[1].invoke()); print(outter[2].invoke()); print(outter[3].invoke()); 运行的结果如何呢?很多初学者可能会得出这样的答案: 然而,运行这个程序,得到的结果为: 闭包有什么特性 其实,在每次迭代的时候,这样的语句 x.invoke = function(){print(i);}并没有被执行,只是构建了一个函数体为”print(i);”的函数对象,如此而已。而当 i=4 时,迭代停止,外部函数返回,当再去调用 outter[0].invoke()时,i 的值依旧为 4,因此 outter 数组中的每一个元素的 invoke 都返回 i 的值:4。 如何解决这一问题呢?我们可以声明一个匿名函数,并立即执行它: var outter = []; function clouseTest2(){ var array = ["one", "two", "three", "four"]; for(var i = 0; i < array.length;i++){ var x = {}; x.no = i; x.text = array[i]; x.invoke = function(no){ return function(){ print(no); } }(i); outter.push(x); } } clouseTest2(); 这个例子中,我们为 x.invoke 赋值的时候,先运行一个可以返回一个函数的函数,然后立即执行之,这样,x.invoke 的每一次迭代器时相当与执行这样的语句: //x == 0 x.invoke = function(){print(0);} //x == 1 x.invoke = function(){print(1);} //x == 2 x.invoke = function(){print(2);} //x == 3 x.invoke = function(){print(3);} 以上就是关于“闭包有什么特性”的内容,希望对大家有用。更多资讯请关注学步园。学步园,您学习IT技术的优质平台!