1.立即执行函数
函数执行完之后,会立刻销毁自己的AO(函数作用域对象)。
(1)(function(){}())。()是立即执行符号,里边可放实参只有表达式才能被执行符号执行,函数声明是不可以的,这里将函数声明用算术运算符()括起来变成表达式。
所谓表达式,由运算符和运算对象组成,单独的一个运算对象也叫表达式,如123,3<9.
(2)被执行符号执行的表达式会被忽略掉名字,因此我们一般不写函数的名字。
2.闭包
当一个内部函数保存到外部的时候就会形成闭包。
e:
function test() { var arr=[]; for(var i=0;i<10;i++){ arr[i] = function () { console.log(i) } } return arr } var a=test(); for(var j=0;j<a.length;j++){ a[j]() }//10,10,10,10,10,10,10,10
test()执行之后,返回数组arr,[fun,fun,fun,fun,fun,fun,fun,fun,fun, fun]
原理:在这里返回数组arr里是一些没有执行的函数。函数执行完会销毁自己的AO对象,但是根据执行上下文,里边的那个函数在定义时就继承了test()函数的AO对象,test()函数的AO对象中有i这个变量。数组中的函数(就是里边的那个函数)没有执行自然不会去寻找i,随着外层的循环,test函数中的i逐渐增加到10,因此在后来我们执行数组的函数时,函数在自己的AO对象中找不到i,自然会去向自己继承的那个父级AO对象中找,而此时的i已经变成了10。
解决方法:
采用立即执行函数
function test() { var arr=[]; for(var i=0;i<10;i++){ arr[i] = (function (j) { console.log(j) })(i) } return arr }原理:将i作为实参保存到每一个函数中。