JavaScript的作用域,让我大吃一斤,没看到还不知道,竟然还有这些注意的地方。
1、对JavaScript作用域的不了解
对很多人应该来说,这个不是问题,但刚刚学习JavaScript的人来说,这应该算是一个细节的忽略。
直接上代码:
对于之前学习其他语言的人来说,***竟然还有这种情况
图为java代码
由上就可以看出,在JavaScript中是没有块级作用域的。那么JavaScript不是无法无天了吗。
2、JavaScript的作用域环境和作用域链
本人对JavaScript的理解,就作用域环境而言,个人认为它就是相当于块级作用域,不过它只包含两个方面:全局环境和函数环境。
所以可以简单的理解成,JavaScript就函数的花括号{ }有用。
在确认环境的范围后,就可以去理解作用域链的关系。(这里就简单的笔记,详细看《高程3》)
作用域链,个人理解,就是在JavaScript中每次运行代码时,都会有一个环境。
在这个简单的代码中就,是在一个环境中执行,而这个环境就是全局环境(在window中就是window)
这是就会产生一条作用域链,这条作用域的前端在window中就是window对象。如图
椭圆形用来代表环境,箭头代表作用域链。
在系统运行到函数的时候,这个时候,作用域的环境就是函数的环境,而作用域链在链接完这个环境后回去寻找,它外层的环境,直到寻找到全局环境。
这里就有一个简单的函数XXX,这时就存在两个环境。
然后我们运行XXX函数。
注:这里说一个应该基础不能再基础的问题,function是定义函数,不运行函数时(给像我一样的菜鸟),所以我们调用函数
或直接运行
这个时候的作用域链就是:
arguments[ ]数组是function的参数(这里就要说到,在JavaScript中函数参数的接受与参数的定义无关,函数有一个自带的数组接收参数,关于函数参数下次笔记里全面的回顾一下,写一下)。
所以在JavaScript执行时当前的环境,需要的识别符(如i,j)回先去当前环境寻找,有没有定义,有的话停止寻找,没有的话接着到下一个环境去寻找直到全局环境,如果都没找到就报错。
3、模拟块级作用域
在ECMAScript 6(简称ES6)中新增了一个“let”使js有了与块级作用域一样的功能。
在没有块级作用域时:
i本来应该在for循环里才比较合适,现在它循环好后就直接出来了。
如果这个时候用let代替
就会被报错。
4、一种不推荐的注意点
JavaScript是一种灵活的语言,在定义一下类型的时候,一定要注意。
在JavaScript
由于函数作用域环境的影响,在全局环境中的“i”是找不到定义的,所以报错。但是如果你去掉var的话
现在应该大致知道了,去掉var后i就变成了全局变量。(但这里不推荐这样用!)