JavaScript实际上是一门奇异的语言,TA的一大特性是没有块级做用域ajax
for(var i=0;i<10;i++){ } console.log(i)
你们猜想下值是多少?
答案是 10, 虽然咱们在一个块内申明了变量,但i倒是在全范围内起做用的,因此就引入了匿名函数闭包
function(){ var i=0; ... }
以函数的做用域来限定变量做用域异步
固然,还当即执行的匿名函数函数
(function(){ do sth..... })()
第一次看到感受真tm古怪,还tm要这样写,太tm古怪了,咱们能够这样看:
定义一个虚拟变量 var foo = function(){...}
而后foo要执行,因此就线程
foo() = (function(){ do sth..... })()
好了,匿名函数就当即执行了code
你们看下面一段代码事件
function foo(){ var arr = []; for(var i =0;i<5;i++){ arr[i] = function(){ //console.log(i) 来看看何时运行 return i; //定义函数时i的值并无初始化,指向函数外的i,所以,当匿名函数运行时,这个值就指向最大的i了 } } return arr; } var a = foo(); //arr的赋值没有被执行 for (var i = 0; i< 5 ;i++){ alert(a[i]()); }
有兴趣的不妨运行一下,答案是5个5,发生什么事了呢?
咱们在对arr赋值的时候:ip
arr[i] = function(){ return i; }
函数里面的i是没有分配具体的值的,它指向了最外层的i,而运行时才会赋值,因此,它就是最大的5了,再看一个例子作用域
var arr = document.getElementsByTagName("p"); for(var i = 0; i < arr.length;i++){ arr[i].onclick = function(){ alert(i); } }
这是一个DOM的onclick事件,当点击的时想可以弹出不一样的i值,其实是没法实现的,因此,必须使用匿名函数的当即执行来限定做用域get
var arr = document.getElementsByTagName("p"); for(var i = 0; i < arr.length;i++){ (function(j){ arr[j].onclick = function(){ alert(j); } })(i) }
这样一段代码
for(var i=0;i<n;i++){ ajax(i,function(....)) //这里是一个异步调用,还有request,http等 }
这里i会是最大值,为什么呢?由于这是一个异步函数,而非同步当即返回的函数,此时因为js奇怪的单线程机制,会待同步所有结束后再运行异步的代码,因此i始终是最大值,那么要用什么方法解决呢?是的,加一个闭包。
这里留下一个问题,若是写成这样,你以为能够么
for(var i=0;i<n;i++){ var j={a:i} ajax(j.a,function(....)) }
总之,js真是一门奇异的语言