写点什么

遇到了几道关于作用域的前端小题

作者:空城机
  • 2021 年 11 月 21 日
  • 本文字数:1253 字

    阅读完需:约 4 分钟

遇到了几道关于作用域的前端小题

在平时的开发过程中,可能考虑各个变量的作用域问题比较少,但是当你找工作时,就会经常遇到这类题目。这里我去看了一下面试题,学到老活到老,学习参考链接:前端面试问题


其中有关于立即执行函数表达式(IIFE)的作用域问题那是更加的层出不穷了。

立即执行函数表达式(IIFE)

立即执行函数,就是在定义函数的时候直接执行,这里不是申明函数而是一个函数表达式


在 JavaScript 中,每一个函数在执行时都会产生一个新的执行环境。由于在函数中定义的变量和函数只能在内部访问而不能被外部访问。这一执行环境调用的函数提供了一个非常简单的方法来创建私有作用域


下面是一个简单的立即执行函数表达式写法:

(function () {    ...})();
复制代码


这里方法的立即执行()前的内容一般需要加括号包围起来,这是告诉解析器这是一个被括号包裹的函数表达式,如果像下面这样写是错误的,报的错误是:Uncaught SyntaxError: Unexpected token ')'


function a() {    console.log(1);}();
复制代码


如果不想使用(),可以在方法前通过=,|,&这些方式来让表达式生效

i = function(){ console.log(1); }();true && function () { console.log(1); }();0, function(){ console.log(1); }();
复制代码


当然,也可以在方法前添加一个一元化运算符,这样做依旧可以生效

+function a() {    console.log(1);}();
复制代码



接下来就看看具体的问题吧

问题 1

非严格模式下执行结果:

(function a () {   a = 2;   console.log(a); })();
复制代码


答案:

ƒ a () { a = 2; console.log(a); }
复制代码


解析:这里的立即执行的函数表达式内部会优先寻找当前作用域下的内容,内部的 a = 2 是变量 a 是属于全局变量,而表达式 a 属于当前作用域,所以会优先执行打印出函数表达式 a。


如果使用的是以下语句,那么会打印出2,因为var a是在当前作用域下定义的。

(function a () {   var a = 2;   console.log(a); })();
复制代码


补充: 同级作用域下,正常定义变量 a 和函数 a,之后打印 a,会优先打印变量。 如果打印 a 在定义之前,那么会打印函数,因为函数的提升是整个代码块提升到它所在的作用域的最开始执行。

问题 2

非严格模式下执行结果:


(function () {   var a = (b = 5); })();console.log(b);console.log(a);
复制代码


答案:


5Uncaught ReferenceError: a is not defined
复制代码


解析:因为 IIFE 中的(b = 5)是全局变量定义,在外部打印时找不到私有作用域中的变量 a,但是可以找到全局作用域中的变量 b。


补充: 严格模式下,不能使用未声明的变量,比如 a = 5;这种定义变量时会出错,必须加上 var 等变量声明方式。

问题 3

非严格模式下执行结果:

data = '101';var Fun = {    data : '123',    getData() {        return this.data;    }}console.log(Fun.getData());newFunGet = Fun.getData;console.log(newFunGet());  
复制代码


答案:

123101
复制代码


解析:这里其实是this指向问题,不同的函数执行环境。this取决于其被谁调用了,而不是被谁定义了当Fun调用getData方法时,this 指向的是Fun。而 newFunGet 中调用getData方法 this 指向的是 window 对象,所以此时的 data 是外面的全局变量




这就是几道简单的作用域小题,边学习边记笔记。

发布于: 1 小时前阅读数: 4
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步

评论

发布
暂无评论
遇到了几道关于作用域的前端小题