购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.20 函数七重关之二(作用域)

“咳咳,那我继续长话短说了。要想回答之前的问题,我必须把作用域的概念再说一说。这便是我所总结的函数七重关里面的第二重关。”叶小凡继续讲解着,这些概念在叶老的教导下早就烂熟于心了。

“首先,作用域如果要深究,还是比较复杂和晦涩难懂的,我就用通俗的话说明作用域的问题吧。在JavaScript中,作用域分为两种,一种是全局作用域,另一种是函数作用域。 所谓作用域,就是指当你要查找某一个变量的时候,你可以在什么范围内找到这个变量 这个寻找的范围,就是作用域 。不管是全局作用域还是函数作用域,都被定义在词法阶段。词法阶段就是刚才所说的JavaScript编译代码的第一个步骤——分词。所以,词法阶段也叫作分词阶段。关于全局作用域,先看一个比较简单的例子。”

“变量a和test函数都直接暴露在外面,因此它们都属于全局作用域。而test函数的函数体,即用花括号包起来的部分则是函数作用域。没错,函数的函数体都属于函数作用域。又因为test函数属于全局作用域,而它自己又拥有一个函数作用域,那么这样一来,就形成了一个作用域的嵌套。也就是说,全局作用域里面嵌套了一个函数作用域。在函数作用域里面可以访问全局作用域中的变量,但是反过来不行。请看刚才的例子。”

“如果我直接调用test函数,答案必然是10。在这个例子中,函数作用域里面的a会先去当前函数作用域里面寻找是否有一个变量a。如果找不到,就去上一层包着它的父级作用域中寻找。那么,从这个例子不难看出,外面的父级作用域,也就是全局作用域中确实有一个变量a。那么,在执行函数体的时候,就可以访问外面的变量a啦。但是反过来就不行,比如这样。”

代码运行结果如下。

“刚才已经说了,全局作用域包着一个函数作用域,在函数作用域里面可以访问全局作用域里面的变量。但是反过来的话,全局作用域想要调用函数作用域中定义的变量却是做不到的。 因此当发生作用域嵌套的时候,只能里面的访问外面的,外面的无法访问里面的 。而且需要注意一点,那就是作用域嵌套一般是针对全局作用域和函数作用域,或者是函数作用域和其他函数作用域而言的。比如,下面这种形式就不是作用域嵌套。”说着,叶小凡随手就打出了一段代码。

代码运行结果是20。

“虽然变量a的定义写在了花括号里面,但是这里并没有出现函数,因此不算作用域嵌套。而且我刚才也说了,在JavaScript中,只有全局作用域和函数作用域,你可以认为这里的a也属于全局作用域,这样更方便理解。既然都是在全局作用域里面,那么console.log方法自然可以访问同为全局作用域里面的变量a。”

叶小凡讲得有理有据,饶是林元青和尹曾琪也微微点了点头。也难怪叶小凡懂的知识比其他弟子多,毕竟,有一个老怪级别的叶老在教导他啊。

“接下来,我把代码换一下。”

“瞧,我现在把if判断中的true改为了false,那么你说,下面的a打印出来是多少呢?”

“这,应该是报错吧,因为定义变量a的语句不会执行了啊。”对面的弟子想了想,不是很确定地说道。

“错了,你看好。”叶小凡微微一笑,运功将代码执行了一下,得到的结果是undefined!

“什么?竟然是undefined,为什么?”对面的弟子惊呼。

“‘ var a = 20 ;’这句话在if判断中,而if判断的条件是false,所以这句话的确不会执行。但是,执行代码是在运行阶段,在代码的分词阶段和解析阶段,变量a依然会被获取,并且系统会默认给它一个undefined。又因为变量a不是在某一个函数的函数体中,而是在全局作用域里面,所以console.log方法依然可以访问这个变量,因此获取变量a的值就是undefined。”

“接下来可以解释之前的那个问题了。”

“第一次执行console.log方法的时候,变量a还没有被赋值为一个函数,但是JavaScript引擎还是会把它提取出来并放入全局作用域,并且默认给它一个undefined。所以,第一次打印出来的就是undefined。接下来就是一个赋值语句了。”

“这个赋值语句把一个匿名函数赋给了变量a,那么从此变量a就指向了这个函数,换句话说,一个名字叫作a的函数就已经产生了。这句话一旦执行,a就不再是undefined了,而是一个函数。接下来执行第二个console.log方法,这个时候a自然已经有值了,所以打印出来的是一个函数。”

“好!好!好!”尹曾琪连说三个好,显然对叶小凡的实力不吝赞赏,他看向叶小凡的眼光中明显多了好几分神采。

“小娃娃,没想到你小小年纪,竟然可以对函数如此了解。既然你提到了作用域分为全局作用域和函数作用域,那么老夫就再来考你一考。”说着,尹曾琪随手一挥,一段代码就显示在了众人眼前。

“这道题你来回答看看,答案是什么呢?”

“答案是undefined,这是在函数作用域里面嵌套了函数作用域,那么在最里面的inner函数中访问一个变量,就会优先在inner函数里面寻找,结果却发现找不到。既然在当前函数作用域里面找不到,那么就往上翻一层,在它的父级作用域,也就是test函数的作用域里面寻找,结果发现找到了。test函数里面定义了一个变量a,但是没有赋值,那么a就是undefined。既然已经找到了,那么就不会去全局作用域里面寻找变量a了。所以,全局作用域里面的变量a其实就是一个摆设。”

“好小子,回答得不错。那你再说说如果函数有参数传递会怎样?”尹曾琪点点头,认可了叶小凡的回答。

场外的观众一下子又沸腾了,要知道,在千鹤派中,尹曾琪可是出了名的严苛,每次考试都喜欢鸡蛋里面挑骨头,很少会像现在这样赞同一个弟子。

“弟子遵命。关于函数的传参,其实我是把它归结为了函数七重关里面的第三重关。”

“哈哈哈,好,好,好。那你就讲讲你的第三重关吧!”尹曾琪哈哈大笑,赞赏之意更浓。

叶小凡抬头看了林元青一眼,得到授意后,就开始讲起了第三重关。 ZajNVY5lBixp5MQ6tCJBFKSsS++sWDqxAey/G4nUNLerr/ej/sv8h0ADMqFKXPzc

点击中间区域
呼出菜单
上一章
目录
下一章
×