如题。
for (令 i = 0; i < 3; i++) {
}
学习是最好的投资!
第一个,你在for里面var i,它们是在同一个作用域的,因为var是一个函数作用域。i = 'abc';i++,这样i就变成NaN了。NaN和数字比较,无论是什么比较,都为false。所以,只输出一次。
for
var i
var
i = 'abc';i++
i
NaN
false
第二个,let是块级作用域,所以在for (let i = 0; ...)定义的i只在for的括号里有效,在块内是没有效果的,所以let i = 'abc'是相当于重新定义了一个变量,是for代码块的块级作用域的变量,只在for代码块里有效。所以执行了三次。
let
for (let i = 0; ...)
let i = 'abc'
第三个问题,你在console.log之后定义了let i,所以i在你调用的时候并没有定义哈。参见上面一条。
console.log
let i
因为变量提升
第一个里面外层的 i 被改变成为 'abc' 所以直接退出,而第二个里面 'abc' 被限制在 for 的块级作用域里面,就不会改变了。
使用var声明的时候 for(var i=0; i<3; i++){} 等价于 var i;for(i=0;i<3;i++){}。这样看就比较明显了第一段代码循环一次是因为:
你在内部将i赋值为字符串,无法进行++操作,for循环只运行了一次就结束了。
第二段代码let 声明的变量只在起所在的块级作用于中生效,上数代码中()、{}是两个块级作用域,他们之间互不影响,定义{}内的i并不会影响()内声明的i
var是函数作用域。在第二次循环判断时i = 'abc'; , 而'abc'++ < 3为false,所以第一个for循环只执行了一次。
i = 'abc';
'abc'++ < 3
let是块级作用域。每次for循环都重新定义了一个i,let i = 'abc'作用域在循环体内,不会影响循环体。
参考这里: http://www.ecma-international...
for 的第一部分是 var (VariableDeclarationList)的时候,声明的变量会合并到这个函数作用域里,就像单独声明一样。
for 的第一部分是 let 的时候,循环会分成 oldEnv 和 loopEnv ,其中 loopEnv 可以看做夹在循环体和循环外的一个中间层,所以不受影响。
第一个,你在
for
里面var i
,它们是在同一个作用域的,因为var
是一个函数作用域。i = 'abc';i++
,这样i
就变成NaN
了。NaN
和数字比较,无论是什么比较,都为false
。所以,只输出一次。第二个,
let
是块级作用域,所以在for (let i = 0; ...)
定义的i
只在for
的括号里有效,在块内是没有效果的,所以let i = 'abc'
是相当于重新定义了一个变量,是for
代码块的块级作用域的变量,只在for
代码块里有效。所以执行了三次。第三个问题,你在
console.log
之后定义了let i
,所以i
在你调用的时候并没有定义哈。参见上面一条。因为变量提升
第一个里面外层的 i 被改变成为 'abc' 所以直接退出,而第二个里面 'abc' 被限制在 for 的块级作用域里面,就不会改变了。
使用var声明的时候
for(var i=0; i<3; i++){} 等价于 var i;for(i=0;i<3;i++){}。
这样看就比较明显了
第一段代码循环一次是因为:
第二段代码let 声明的变量只在起所在的块级作用于中生效,上数代码中()、{}是两个块级作用域,他们之间互不影响,定义{}内的i并不会影响()内声明的i
var是函数作用域。在第二次循环判断时
i = 'abc';
, 而'abc'++ < 3
为false,所以第一个for循环只执行了一次。let是块级作用域。每次for循环都重新定义了一个i,
let i = 'abc'
作用域在循环体内,不会影响循环体。参考这里: http://www.ecma-international...
for 的第一部分是 var (VariableDeclarationList)的时候,声明的变量会合并到这个函数作用域里,就像单独声明一样。
for 的第一部分是 let 的时候,循环会分成 oldEnv 和 loopEnv ,其中 loopEnv 可以看做夹在循环体和循环外的一个中间层,所以不受影响。