前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >闰土说JS进阶之作用域链

闰土说JS进阶之作用域链

作者头像
闰土大叔
发布2018-04-12 11:01:49
7080
发布2018-04-12 11:01:49
举报
文章被收录于专栏:闰土大叔闰土大叔闰土大叔

前言

在前端应聘中,相信会有不少面试官都会问你,说说你理解的js作用域,或者作用域链。显然,这是一道经典的js面试题,对于老司机而言可谓是小菜一碟,而对于前端新人,尤其是js基础不扎实的新人来说,则会说的模棱两可,含糊其辞。当然这样青涩的答案显然不会入面试官的法眼,甚至会让你白白丢掉一次面试机会。那么作用域链究竟好不好理解呢,接下来正文开始。

在说作用域前,我们先来说说什么是执行环境。新人容易把执行环境和作用域这两个概念搞混了,要知道函数的每次调用都有与之相关的作用域和执行环境。从根本上来说,作用域是基于函数的,而执行环境是基于对象的,举个栗子,全局执行环境是window对象。

执行环境,同行们也喜欢叫执行上下文。每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。

执行环境分为创建和执行两个阶段。在创建阶段,解析器首先会创建一个变量对象,也叫活动对象,俗称AO。它由定义在执行环境中的变量、函数声明和参数组成。在此期间,作用域链会被初始化,this的值也会被确定。而在执行阶段,代码便会被解释执行。

如果这时面试官问你作用域链的作用是什么?你是不是会瞬间懵逼?别急。且听闰土怎么说。那么这个问题的标准答案就是,作用域链的用途是用于解析标识符。(知道了吧,是不是该用笔记下来,或者划划重点啥的,闰老师说了,这是必考题,嘿嘿~)

标识符的解析是从作用域链的前端开始,沿着作用域链一级一级向后回溯,直至找到标识符为止。(如果找不到,则会报错)。

说了这么久,给大家举个栗子:

var food = '麻辣烫';



function changeFood(){
    var anotherFood = '过桥米线';


    function swapFood(){
        var tempFood = anotherFood;

        anotherFood = food;

        food = tempFood;

 

        //这里可以访问food、anotherFood、tempFood

    }



    //这里可以访问food、anotherFood
    swapFood();

}

//这里只能访问food
changeFood();

以上代码中,在swapFood()函数的局部环境中有个变量tempFood,这个变量只能在这个环境中访问到。无论全局环境还是changeFood()的局部环境都无权访问tempFood。而在swapFood()内部则可以访问其他两个环境中的所有变量,因为那两个环境是它的父执行环境。

总结一下,内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数。

接下来,我们再来讲讲块级作用域。

在ES6没出来之前,javascript是没有块级作用域的。在这一点上,很多从后端转过来的前端人员都比较困惑,因为在C++或者java中,由花括号封闭的代码块都有自己的作用域,用ES自己的话来说,就是它们自己的执行环境。这也是我认为的js的一个缺陷。让我们一起来看看下面这个for循环的栗子:

for(var i=0;i<10;i++){
    console.log('i: ' + i);

}

console.log(i);  // 10

对于有块级作用域的语言来说,i变量会在for循环执行结束之后销毁,换句话说,它只会存在循环体内。而对于javascript来说,变量i即使在for循环执行结束以后,也依旧会存在于循环体外部的执行环境。所以最后console出来的i 是 10。扩展一下,如果用ES6的let来声明变量i,那么console出来的结果就是 i is not defined。因为ES6中的let声明的变量具有块级作用域的特性。

在javascript编码过程中,不声明而直接初始化一个变量是一个常见的错误做法,因为这样可能会导致意外。所以,想要了解大公司的javascript编码规范,首先要从细节开始,从初始化变量前先声明开始。

小结

每天进步一点点,每天消化掉一个小知识点,才能积少成多,最后量变导致质变。愿大家都能成为更好的前端,做更好的自己。

最后给大家放个彩蛋,看闰土哥在公园玩俯卧撑快闪,请为闰土少年打call!

视频内容
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-10-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 闰土大叔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档