Javascript基本功 作用域 深入学习

版权声明:本文为原创文章,未经博主允许不得转载,欢迎各种交流,共同进步。 https://blog.csdn.net/sinat_15951543/article/details/80392290

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

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


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

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

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

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

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

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

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


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

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

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

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


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

函数作用域

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

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

请阅读以下代码:

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

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

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

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

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

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

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

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

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

块作用域

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

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

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

猜你喜欢

转载自blog.csdn.net/sinat_15951543/article/details/80392290