关于JavaScript在函数中的变量申明的问题(建议新手必读)

107 阅读2分钟

为了巩固一下基础,最近在阅读关于《JavaScript语言精粹》这本书,看到作用域这部分有一些新的发现,那么现在做一个小的总结,相信你会有收获。

来看几行经典代码

对js有一定熟悉程度的同志一定不难看出,a最后的结果是1。
那么这是为什么呢?
一行一行代码来看,它做了这么几件事。

  1. var a = 1; //申明a变量的值等于1,也就等同于为window添加一个a属性,值为1.
  2. 预处理时创建函数foo。
  3. 调用函数foo,当代码执行到foo()的时候,函数foo被压入调用栈当中执行第一行代码var a = 2; 需要注意的是var a = 2;这一行代码,在foo()当中创建的a变量只是一个临时变量,并不等同于外部的全局a变量,并不会挂载在window对象当中,所以当函数调用完成以后,该函数被弹出调用栈,js进行内存清理,于是内部a被销毁,最后打印a,a=1
    也可以简单理解为块级作用域,外部无法访问内部变量

提问:当把var a = 2;中的var关键词去掉,那么最后a的值会不会变化呢?
答:当然会变,结果变为2。很好理解,涉及到一个简单的知识点,不使用var申明变量,那么该变量会直接添加在window对象上,成为一个属性,其实使用var申明变量也会成为window的一个属性(在全局情况下),当然其中会有一定的区别,其中最大的区别就是未用关键字申明的变量可以使用delete直接删除。当直接使用a = 2,那么就相当于window.a = 2,于是a的值将会发生改变

总结

  • 在函数中使用保留字申明变量,变量会被暂存在临时栈区,并不会被挂载在window上
  • 关于js的作用域问题其实是有一些混乱的,在非严格模式下,单从在函数中可以申明局部变量来看,它是支持块级作用域的,在非函数作用域下,申明任何变量在任何地方都是可以访问的,这一点却又和块级作用域相悖论,这也是js的一些缺陷,但随着不断发展,js也在不断完善。
  • 暂时想到这么多,也许有些其他的没想起来,欢迎补充