知识点与实例代码
闭包
for循环情况下的常见闭包
for (var i = 0; i < 5; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i);
}
每隔一秒
依次输出0 1 2 3 4
。
修改一下,去掉匿名函数里面的i
:
for (var i = 0; i < 5; i++) {
(function() {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i);
}
此时,输出5 5 5 5 5
。
为什么?因为去掉外面的i
后,匿名函数里面的i
就要按作用域链向外部查找同名变量,便找到了for
循环中的i
,等到setTimeout
中函数执行时,i
已经是5了。
怎么理解去掉i
之后内部函数向查找i
的过程呢?把匿名函数改成非匿名函数来看:
function outter(){
var str='1'
function inner(str){
log(str)
}
inner(2);
}
outter(); //2
function outter(){
var str='1'
function inner(){
log(str)
}
inner(2);
}
outter(); //1
第一个得到2
,是因为inner(2)
由于函数定义了一个接收参数str
而传入到了函数内部。
第二个得到1
,是因为没有str
,虽然也传了2
,但是没有能接收的变量,只能去向outter
函数内部查找同名变量,找到了1
。
同理,匿名函数定义时没有形参也是这样,内部的变量只能顺着作用域链向外部寻找同名变量。
setTimeout(fn,0)
setTimeout(function(){
log('Where am I ?')
},2)
setTimeout(function(){
log('What\'s the difference ?')
},3)
setTimeout(function(){
log('Oh no!')
},2)
setTimeout(function(){
log('what?!')
},0)
setTimeout(function(){
log('hhhh?!')
},0)
setTimeout(function(){
log('what about this one?!')
},0)
经过多次尝试,我发现setTimeout(fn,0)
与setTimeout(fn,1)
的作用基本一样,无论是0或1,基本都可以当做0来处理,不影响执行顺序。至于setTimeout(fn,2)
就不一样了,和0,1比起来,明显有了延后。
至于如何理解,我是把0,1都看做0,剩下的来比较出现的先后顺序,对于计算机来说,毫秒也是很大的数值了,所以不用考虑setTimeout(fn,3)
都是3的情况下怎么考虑其他不是3的项,原则就是,谁在前谁先执行。
上面的输出结果是:
what?!
hhhh?!
what about this one?!
Where am I ?
Oh no!
What's the difference ?