遇到了几道关于作用域的前端小题
在平时的开发过程中,可能考虑各个变量的作用域问题比较少,但是当你找工作时,就会经常遇到这类题目。这里我去看了一下面试题,学到老活到老,学习参考链接:前端面试问题
其中有关于立即执行函数表达式(IIFE)
的作用域问题那是更加的层出不穷了。
立即执行函数表达式(IIFE)
立即执行函数,就是在定义函数的时候直接执行,这里不是申明函数而是一个函数表达式
在 JavaScript 中,每一个函数在执行时都会产生一个新的执行环境。由于在函数中定义的变量和函数只能在内部访问而不能被外部访问。这一执行环境调用的函数提供了一个非常简单的方法来创建私有作用域
下面是一个简单的立即执行函数表达式
写法:
这里方法的立即执行()
前的内容一般需要加括号包围起来,这是告诉解析器这是一个被括号包裹的函数表达式,如果像下面这样写是错误的,报的错误是:Uncaught SyntaxError: Unexpected token ')'
如果不想使用()
,可以在方法前通过=
,|
,&
这些方式来让表达式生效
当然,也可以在方法前添加一个一元化运算符,这样做依旧可以生效
接下来就看看具体的问题吧
问题 1
非严格模式下执行结果:
答案:
解析:这里的立即执行的函数表达式内部会优先寻找当前作用域下的内容
,内部的 a = 2 是变量 a 是属于全局变量
,而表达式 a 属于当前作用域
,所以会优先执行打印出函数表达式 a。
如果使用的是以下语句,那么会打印出2
,因为var a
是在当前作用域下定义的。
补充: 同级作用域下,正常定义变量 a 和函数 a,之后打印 a,会优先打印变量。 如果打印 a 在定义之前,那么会打印函数,因为函数的提升是整个代码块提升到它所在的作用域的最开始执行。
问题 2
非严格模式下执行结果:
答案:
解析:因为 IIFE 中的(b = 5)
是全局变量定义,在外部打印时找不到私有作用域中的变量 a,但是可以找到全局作用域中的变量 b。
补充: 严格模式下,不能使用未声明的变量,比如 a = 5;这种定义变量时会出错,必须加上 var 等变量声明方式。
问题 3
非严格模式下执行结果:
答案:
解析:这里其实是this
指向问题,不同的函数执行环境。this
取决于其被谁调用了,而不是被谁定义了当Fun
调用getData
方法时,this 指向的是Fun
。而 newFunGet 中调用getData
方法 this 指向的是 window 对象,所以此时的 data 是外面的全局变量
这就是几道简单的作用域小题,边学习边记笔记。
版权声明: 本文为 InfoQ 作者【空城机】的原创文章。
原文链接:【http://xie.infoq.cn/article/d1391ea59ac5bf317c068ba86】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论