for(i=0;i<10 ;i ) {//다음과 같이 쓰지 마세요: var i=0 alert(i); }
그러나 이것은 실제로 좋은 습관이 아닙니다. 내가 Js를 작성하는 이유에 대해 for 루프에 var를 추가해야 합니다. 그렇지 않으면 때때로 짜증나고 찾기 어려운 버그가 발생할 수 있습니다. 예를 들어, 이제 다음 함수를 구현하려고 합니다. 출력 10 20 30 40 50 60 70 80 90 100 다음 코드를 통해 WriteNumber는 1부터 10까지 반복하며, 각 루프는 TenTimes 메서드를 호출하여 인덱스 값의 10배를 반환합니다.
> 결국 10개만 출력되는 것을 볼 수 있습니다. 아래 코드 상자를 사용하여 테스트를 실행할 수 있습니다.
[Ctrl A 모두 선택 참고: 외부 J를 도입해야 하는 경우 실행하려면 새로 고쳐야 합니다 ] 关于在WriteNumber和TenTimes方法里加不加var,就是说是否声明索引变量i有4种情况: 第一种情况,WriteNumber和TenTimes各有1个for循环,2个循环里均没有用var声明i索引变量。 运行结果:会alert出1。结果只输出了10,不是我们所想要的。 分析:执行WriteNumber时,其作用域内并没有找到声明过的变量i,直接对i进行赋值,则隐式的将i声明为全局变量,(对于函数内部未声明过的变量,如果给它赋值,会隐式的将它声明为全局变量。) 循环开始,i=1,调TenTimes方法,发现TenTimes方法也没有声明过变量i ,所以TenTimes里的i就是全局变量i,就和WriteNumber的i成了同一个。 这时line9 alert出来的自然是1了。TenTimes循环了10次,使得全局的i变成了11,自然WriteNumber就不会执行第2次循环操作了。 验证:如果在WriteNumber();语句后加alert(i),即取消line16的注释,会发现alert出12(12=10+2个i++),证明了i此时为windows对象。 第二种情况,WriteNumber声明了i变量,即line3: var i=1,TenTimes未声明i变量,即line10: i=1。 运行结果:line9 alert(i)处报i未定义错误 ,因为WriteNumber有声明过变量i,所以没有成为全局的i,TenTimes执行时又没有声明过i,所以报未定义。若注释掉line9,输出结果正确。因为当TenTimes里运行到i=1时,隐式将i声明是全局变量,不影响WriteNumber里的i。WriteNumber仍然会执行10次循环。 验证:如果在WriteNumber();语句后加alert(i),即取消line16的注释,会发现alert出11(11=10+TenTimes里的i++),证明了此时有windows.i。 第三种情况,WriteNumber没有声明i变量,即line3: i=1,TenTimes声明了i变量,即line10: var i=1。 运行结果:弹出10个undefined。因为WriteNumber未声明i,隐式将i声明是全局变量,而TenTimes有声明过变量i(补充一句,对于变量的声明都是在预编译中进行的),所以line9 alert(i)里的i不是windows.i,而是TenTimes声明的变量i,此时当然是undefined了。同时,发现输出结果正确,因为TenTimes的i不会影响WriteNumber的全局i,WriteNumber仍然是执行了10次循环。 第四种情况:WriteNumber和TenTimes均用var声明了i。 运行结果:注释掉line9,不说了,好习惯,结果当然完美。 虽然第二、三种情况输出结果是正确的,但是对i的使用很混乱,应该算是运气导致结果正确,因为刚好1个是window.i,一个是函数内部的私有变量i,使得没有冲突。 此文虽然讲的是写for循环为什么一定要加var,但其实讲的是变量的作用域(或者说变量的生命周期)。理解之后,下面的2段code运行结果你应该能准确说出答案吧。