Javascript基本功 作用域 深入学习

港控/mmm° 2022-05-24 05:12 252阅读 0赞

聊起作用域,很多小伙伴并不陌生,是所有编程语言最基本的功能之一,就是在某个范围内储存变量的值。

也可以说,“作用域就是根据名称查找变量的一套规则”。

想入深入学习作用域,必先理解作用域。

理解后面一行代码在底层的工作原理: var a = 1 ;

这条语句在编译器会并不是一步处理掉的,它会被拆分成两条语句,var a ,a = 1 。

var a ,编译器会先查询询问变量a是否存在,再做声明操作。

a = 1,编译器也是一样,查询询问变量a是否存在,再做赋值存在。

由此看见,机器毕竟还是机器,每当碰到变量必先进行查询,询问作用域里面是否存在变量。

那么,如果作用域中找不到变量怎么办?一直往上层的作用域寻找,直到最外层的全局作用域,不管有没有找到,查找过程都会停止。

作用域按照工作模型来划分,作用域分两种,一种是词法作用域,一个动态作用域。

词法作用域:在代码的位置决定作用域,词法分析器处理代码的时候会保持作用域不变。

动态作用域:在运行的位置决定作用域。

换一句话来说,就是词法作用域关注函数在哪里声明,动态作用域关注函数从哪里调用。Javascript是属于词法作用域。

作用域按照容器区域来划分,作用域可以分为函数作用域和块作用域。

函数作用域

在Javascript中,每一个函数都有自己的函数作用域。属于这个函数的全部变量都可以在整个函数的范围内使用及复用。

但是在某些场合,我们必须要隐藏作用域(很多原因促成这个隐藏方法,比如避免冲突,变量污染等。)

请阅读以下代码:

  1. var a = 1 ;
  2. function demo(){
  3. var a = 2;
  4. console.log(a);//2
  5. }
  6. demo();
  7. console.log(a); //1

这代码里面展示了函数作用域,可以在函数作用域里面做一些只能在作用域才能进行的操作。但是这个代码并不理想,这么运行会附带一些额外的问题,首先它声明了一个demo函数,污染了所在的作用域;其次需要再次运行demo()才能运行函数内代码。

为了解决上述问题。请阅读下面代码

  1. var a = 1 ;
  2. (function demo(){
  3. var a = 2;
  4. console.log(a);//2
  5. })();
  6. console.log(a); //1

这代码的函数前面加了 “(” 号,函数将以函数表达式的声明方式来声明。

这个做法解决了之前的弊端,避免了声明函数名来污染作用域,而且能给函数内部代码一个独立的运行作用域。

其实这个方法有另外一种名字,就是IIFE(立即执行函数表达式),这个函数名对于IIFE并不是必须的。

IIFE的作用非常广,下面是它的主要三个推广实践的优势。

  1. 创建只使用一次的函数,并立即执行它。
  2. 创建闭包,并保持状态,隔离作用域。
  3. 作为独立模块存在(如JQuery),防止命名冲突,命名空间注入,模块解耦。

块作用域

这个概念很可惜,在ES5之前,Javascript要实现块作用域是非常痛苦的事情。

在ES6之后,可以通过 let 关键字变量声明隐隐式地劫持所在的块作用域,达到块作用域的效果。

但是let进行的声明不会在块作用域内进行声明提升,只有 var 和 函数声明 才会进行声明提升。

发表评论

表情:
评论列表 (有 0 条评论,252人围观)

还没有评论,来说两句吧...

相关阅读