当前位置: 首页 > Web前端 > JavaScript

顶部===窗口?因为在使用var

时间:2023-03-27 12:32:25 JavaScript

时遇到的坑,今天有同学问了一个bug,这是平时很难发现的一个方面,所以写了一篇文章介绍一下。起因是今天被同学求助,帮我找出代码哪里出了问题。我要实现的功能很简单,就是一个登录窗口的弹出和关闭。但是遇到了一个bug,窗口无法关闭。代码如下,省略了部分内容,你能找到问题所在吗?点击弹出登录框

关闭登录
vartop=document.querySelector('.top')varbox=document.querySelector('.box')varbody=document.bodyvarclose=document.querySelector('.close')top.addEventListener('click',function(){box.style.display='block'body.style.background='#b2b2b2'})close.addEventListener('click',function(){box.style.display='none'body.style.background=''})一开始看代码,感觉逻辑还是挺对的。看他的测试结果,事件也绑定正确。折腾了一会儿,我才让他把代码发给我,自己调试才知道。顶部变量的棘手打印实际上指向窗口???每次点击关闭,因为事件冒泡,关闭的窗口又被打开了到底,这是var导致的bug。我们知道var声明的变量都是绑定到window上的。我们使用这些变量来省略window的部分。但是,window有一些变量是不能改写的。而var声明的是已经存在的变量,不会报错。这导致我们认为一个变量被正确地声明和赋值,但我们实际上是在使用浏览器内置的window属性。window.top属性返回对窗口层次结构中最顶层窗口的引用,并且是一个无法重写的属性。这也导致了前面代码中声明了top节点绑定事件,但是事件实际上是绑定到window上的。窗口上有很多属性,最多200个,其中很多是常用的变量名,名称长度parentself等。幸运的是,这些变量都是可写的,我们声明和使用它们都没有引起任何错误。为什么说是var引起的呢?因为如果用let定义top变量,会直接报错lettop=1//SyntaxError:Identifier'top'hasalreadybeendeclared对于那些可写的窗口属性,let可以正常声明和赋值,不会修改window上的属性,使用时也是用let声明的变量。解决这个问题。不常遇到,但遇到了很难排查。窗口属性就这么多,以后会继续添加的。也许他们会在某个时候遇到他们。这里有一个解决办法:一是拒绝使用var,只使用letconst来声明变量,二是启用JavaScript文件的检查功能。在vscode中,可以在setting.json文件中设置"js/ts.implicitProjectConfig.checkJs":true来启用JavaScript文件的语义检查。这个语义检查功能非常有用。可以帮助大家排查js文件不规范的问题,比如参数类型,变量是否已经声明等等,帮助我们养成良好的编码习惯。结论文中如有错误或不准确之处,请务必指正,万分感谢。如果你喜欢或启发了一些东西,我希望你能喜欢它并关注它以鼓励作者。