let 会报错, var 才能正常运行? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
Cielos
V2EX    Javascript

let 会报错, var 才能正常运行?

  •  
  •   Cielos 2020-04-09 18:39:38 +08:00 3949 次点击
    这是一个创建于 2017 天前的主题,其中的信息可能已经有所发展或是发生改变。
    window.Onload= function () {
    var gogogo;
    let btn1 = document.getElementById('btn1');

    btn1.Onclick= function () {
    clearInterval(gogogo);
    var gogogo = setInterval(function () {省略...})
    }

    各位好,我刚学 JS 没多久,跟着李立超的视频学的。
    上面这段代码里,如果我把 var gogogo 改成 let,压根就没法运行,请问是什么原因啊?
    还有 clearInterval()应该可以中止定时函数,但是并没有中止,重复点击依然有效,这又是什么情况?

    PS: 李立超的教程是 2016 年录的,当时还没有 LET 吧,像我这样的初学者应该去哪里了解 LET 的详细用法呢?
    26 条回复    2020-04-10 20:54:29 +08:00
    ccyu220
        1
    ccyu220  
       2020-04-09 19:00:22 +08:00
    let 不允许重复声明,都用了 es6 你重复声明 let gogogo 干嘛。
    ccyu220
        2
    ccyu220  
       2020-04-09 19:00:43 +08:00
    baxtergu
        3
    baxtergu  
       2020-04-09 19:07:31 +08:00
    这样改应该就可以了,let 定义的变量名不允许重定义,但是允许重复赋值。

    window.Onload= function () {
    let gogogo;
    let btn1 = document.getElementById('btn1');

    btn1.Onclick= function () {
    clearInterval(gogogo);
    gogogo = setInterval(function () {省略...})
    }
    useben
        4
    useben  
       2020-04-09 19:08:32 +08:00   5
    我是被头像吸引进来
    wangyzj
        5
    wangyzj  
       2020-04-09 19:28:10 +08:00
    @useben +1
    Cielos
        6
    Cielos  
    OP
       2020-04-09 19:30:59 +08:00
    @baxtergu 仅仅是去掉一个 let 就可以了吗!谢谢大佬!!!
    Cielos
        7
    Cielos  
    OP
       2020-04-09 19:32:51 +08:00
    @ccyu220 谢谢大佬了!所以 var 是可以重复定义的是吗
    ljpCN
        9
    ljpCN  
       2020-04-09 19:45:01 +08:00 via Android
    @Cielos 在你贴的代码里,如果用 var,里面的函数里的和外面的函数里的 gogogo 就不是同一个变量了。
    suckli
        10
    suckli  
       2020-04-09 20:07:41 +08:00
    我是被头像吸引进来
    lzxz1234
        11
    lzxz1234  
       2020-04-10 08:32:21 +08:00
    提问的艺术第一条:换个好头像
    fueen
        12
    fueen  
       2020-04-10 09:16:39 +08:00
    头像+1
    iMiata
        13
    iMiata  
       2020-04-10 09:28:05 +08:00
    头像选得好,绅士少不了
    wgbx
        14
    wgbx  
       2020-04-10 09:57:58 +08:00
    论头像的重要性,var 可以重复声明,let 不允许,ps:var 作为一种过时的声明方式,建议只使用 let 和 const
    ElmerZhang
        15
    ElmerZhang  
       2020-04-10 10:19:57 +08:00
    建议楼主读一下 《 ES6 标准入门》
    ElmerZhang
        16
    ElmerZhang  
       2020-04-10 10:21:16 +08:00
    除非完全没有编程基础,否则学习一门新语言时最好买本书从基本语法入手。
    werty
        17
    werty  
       2020-04-10 11:13:24 +08:00
    头像+1
    Curtion
        18
    Curtion  
       2020-04-10 14:49:33 +08:00
    这是因为 let 暂时性死区问题,onclick 中调用 clearInterval 函数时会用到 gogogo 变量,此时因为使用了 let 所有存在 TDZ 问题,导致并不会向上级作用域寻找 gogogo 变量,所有会报 Cannot access '' before initialization 错误。

    clearInterva 没有中止有两个原因,一是因为 onclick 中使用了 var 定义变量,每次点击时的 gogogo 都是新的,结果就是不但没有停止,每次点击时还新建了一个定时器;如果把 var 去后也无法停止,原因是虽然停止了定时器,但是又新建了一个定时器。


    我感觉很奇怪的就是:
    console.log(a)
    let a = "1"
    报的错误是:Uncaught ReferenceError: a is not defined


    而:
    function main() {
    console.log(a)
    let a = "1"
    }
    main()
    报的错误是:Uncaught ReferenceError: Cannot access 'a' before initialization

    我怎么感觉这是同一种错误....
    djs
        19
    djs  
       2020-04-10 15:27:16 +08:00 via iPhone
    let 可以导致暂时性死区,在你用的 let 那个位置,要先生命变量才行
    vivipure
        20
    vivipure  
       2020-04-10 15:37:59 +08:00
    建议 直接看 ruanyifeng 的 ES6 或者 MDN 文档
    kingthy
        21
    kingthy  
       2020-04-10 16:42:46 +08:00
    @Curtion 是同一个错误,ReferenceError,只是描述不一样,你把它看为第一种是编译期错误,第二种是运行期错误。比如第二种 function main() {
    console.log(a)
    let a = "1"
    }
    kingthy
        22
    kingthy  
       2020-04-10 16:43:17 +08:00
    怎么自动发布了,补上面:
    kingthy
        23
    kingthy  
       2020-04-10 16:44:07 +08:00
    怎么自动发布了,补上面:方法定义后不执行是可以“编译”通过的
    ourFEer
        24
    ourFEer  
       2020-04-10 17:39:59 +08:00
    我是被头像吸引进来的
    Cielos
        25
    Cielos  
    OP
       2020-04-10 19:38:29 +08:00
    非常感谢大家的回答!
    theohateonion
        26
    theohateonion  
       2020-04-10 20:54:29 +08:00
    @ccyu220 并不是 let 不允许重复声明,而是 18 楼说的死区问题
    关于     帮助文档     自助推广系统     博客     API     FAQ       2630 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 14:21 PVG 22:21 LAX 07:21 JFK 10:21
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86