1
swirling 2016-09-23 13:36:31 +08:00
var i = 0;
for(; i<3; i ++){ funcList.push(function(){ console.log(i); }) } 这样不就好理解了吗。。。 |
2
viko16 2016-09-23 13:40:51 +08:00
执行函数的时候才去读 i 的值
|
3
learnshare 2016-09-23 13:46:12 +08:00
经典坑 Number 0
|
4
hronro 2016-09-23 13:47:55 +08:00 via Android
for 小括号里面第一个语句,定义的变量 i ,是全局变量 i ,没什么不好理解的吧
|
5
lovedebug 2016-09-23 13:51:12 +08:00
JS 在 ES6 之前 for 循环没有块作用域
|
6
loushizan 2016-09-23 13:52:09 +08:00
var funcs = [];
for (var i = 0; i < 3; i++) { (function(i) { funcs.push(function() { console.log(i); }); })(i); }; |
7
kimown 2016-09-23 13:54:28 +08:00
论 ES6 的巨大进步
|
8
Skyxianbo 2016-09-23 13:55:40 +08:00
没什么不好理解的, var 定义的 i 是全局的,等你在第二个循环里面调用的时候才去读 i 的值,这个时候的 i 已经经过第一个循环然后变成 3 了。你把 var 换成 let ,这样定义的 i 只在第一个循环里面起效果,就不会出现这样的问题了。可以去看看 ES6 的块级作用域。
|
9
aristotll 2016-09-23 13:56:05 +08:00
用 let...
|
10
think2011 2016-09-23 14:05:00 +08:00
let let let
|
11
wallax 2016-09-23 14:09:39 +08:00
不用 let 也能解决 只要控制好作用域就行了
var funclist = []; var func = function(a){ funclist.push(function(){console.log(a)}); }; for(var i = 0; i < 3; i++){ func(i); } for(var j = 0; j < 3; j++){ funclist[j](); } |
12
iyangyuan 2016-09-23 14:10:15 +08:00
入门问题
|
13
SuperMild 2016-09-23 14:22:30 +08:00 via iPad
如非必要就别用旧标准了, let 已经得到广泛支持。
|
14
js0816 2016-09-23 14:22:54 +08:00
let 替换 var 就 O 了
|
15
prefere 2016-09-23 14:51:52 +08:00
问个小白问题,这个菊部变量 i 存哪了?
http://imgur.com/KV5NjMA.jpg |
16
prefere 2016-09-23 14:52:46 +08:00 1
更正: 菊>局
|
17
prefere 2016-09-23 14:54:44 +08:00
|
18
zhouyg 2016-09-23 16:07:18 +08:00
一点开我就猜是这个问题,😄太经典。
|
19
defia 2016-09-23 17:10:13 +08:00 via iPhone
闭包内保留的是变量引用
|
20
cheneydog 2016-09-23 17:13:06 +08:00
典型的闭包问题
|
21
FrankFang128 2016-09-23 17:22:06 +08:00
搞不懂 var ,最后去用 let 。
呵呵。 |
22
wangcansun 2016-09-23 17:22:27 +08:00
所以 es6 中使用 let 了
|
23
ianva 2016-09-23 17:30:39 +08:00
ES6 的实现:
[1,2,3].map( num=>()=>console.log(num) ).forEach(fn=>fn()) 在大部分的情况下 map, filter, reduce, forEach 代替 for 要简单的多 |
24
ianva 2016-09-23 17:40:43 +08:00
再彻底一点:
[...Array(3).keys()].map( num=>()=>console.log(num) ).forEach(fn=>fn()) |
25
21grams 2016-09-23 17:50:12 +08:00
别再用 var 了,全部用 let
|
27
fundon 2016-09-23 18:27:27 +08:00
安利下 「 ES6: 快速体验,及实用小贴士」 https://github.com/fundon/ES6-QuickStart-and-Tips
|
28
vwok 2016-09-23 18:35:08 +08:00 1
@prefere ![]( http://imgur.com/Ob8Y855) 看的讲闭包的都没讲到原型结构啊,今天终于知道 closure 是怎么来的了
|
29
sudoz 2016-09-23 18:36:39 +08:00
入队的时候没有执行 console.log 啊
|
30
hronro 2016-09-23 18:40:35 +08:00 via Android
楼上的各位说用 let 的,现在没人敢直接在生产环境下直接用 let 吧?都是要 babel 编译之后才能用的。如果只是一个小程序的话,上 babel 的成本又太高了
|
31
yhxx 2016-09-23 22:56:08 +08:00
因为 let 提供了块级作用域
|
32
magicdawn 2016-09-24 02:12:29 +08:00
1. 闭包不是 js 专利, 在 gopl 上看到 golang 也有这个问题
2. 使用 let 解决的解释 - https://cnodejs.org/topic/56c7d5cf5a619f490208f9cc - https://cnodejs.org/topic/56c7d5cf5a619f490208f9cc#56c9a25d92cca07861f942d0 - http://dmitrysoshnikov.com/ecmascript/javascript-the-core/comment-page-3/#comment-173985 |
34
YuJianrong 2016-09-24 08:30:31 +08:00 via iPhone
@hronro 成本高在哪?编译出来大小增加不大啊。
如果用到一些增强的内置函数需要挂 polyfill ,但这个可以自己挑需要什么啊,即使全部挂上也没多大。 |
35
Bensendbs 2016-09-24 10:03:23 +08:00
用 let...var 有作用域提升的问题..
|
36
winiex 2016-09-24 10:31:13 +08:00
let 的作用于是我们常见意义上的块级作用于,而 var 的作用域则仅适用于 function ,一般意义上的 code block 对它没有作用域的限制意义。从编程语言的角度来看, var 声明的变量的作用域部分是不完整的。建议用 let 。
[“ let ” keyword vs “ var ” keyword in Javascript]( http://stackoverflow.com/questions/762011/let-keyword-vs-var-keyword-in-javascript) |
37
zongren 2016-09-24 10:34:23 +08:00
用闭包也能解决吧
|
38
wizardforcel 2016-09-24 11:16:58 +08:00
@prefere 每个函数在调用时都会有一个帧,局部变量当然是存到帧里面。但是有的帧在函数返回时会销毁, lz 这种情况不会。因为函数中的函数会关联外层函数的帧,这个帧还有函数在用就没法销毁。
|
39
poke707 2016-09-24 16:30:22 +08:00
这个可以说是 Javascript 的坑也可以说是 feature 。虽然有意这样写的情况不多见吧。
重要的是要理解编程语言本身,变量的值和引用啊,作用域啊,语法和表达式啊。 如果不重视基本功, ES6 照样会踩坑。 比如 [1,2,3].map(n => {value: n}) 有人觉得会返回他以为的东西,有人觉得会报错(比如我,我都忘了有 label 这回事)。 但结果是不但不报错还会返回 [undefined, undefined, undefined] 呢。 |
40
neone 2016-09-24 18:58:10 +08:00
JS 的经典问题。
`var` 声明是没有块级作用域的,所以上面的代码等于: ``` var i; for (i = 0; i < 3; i++) { funcList.push(function() { console.log(i); }); } ``` ES5 中可以使用闭包解决, ES6 中直接使用`let`即可。 `let`声明的变量具有块级作用域,所以 3 次循环会产生 3 个不相同(仅同名)的变量`i`,添加入数组中的函数引用的是不同的变量。事实上你在循环的外部先用`let`定义变量`i`,那么结果也都是 3 3 3 ,如下: ``` let funcList = []; let i; for (i = 0; i < 3; i++) { funcList.push(() => { console.log(i); }); } for (let j = 0; j < 3; j++) { funcList[j](); } ``` |
41
itisthecon 2016-09-24 20:40:01 +08:00
想通了这个基本就能填上变量申明提升的坑了
> var myvar = 'global value'; > (function() {console.log(myvar);var myvar='local value';})(); undefined |