详解js的作用域、预解析机制


Posted in Javascript onFebruary 05, 2018

虽然,ES6在我们工作中应用得越来越广泛,但是还是很多项目保留着ES5的写法,所以,今天,带着大家重新巩固下ES5下的作用域及预解析机制。

概念:

作用域:域,指的是一个空间、范围、区域,作用指的是在域内可进行读写操作。一个变量的作用域是程序源代码中定义的这个变量的区域。

在ES5中,只存在全局和函数级作用域,在ES6中,引入了块级作用域,js的预解析机制大概分为两个过程:预解析和自上而下逐行解读

预解析:js解析器会先把var定义的变量、function、参数等一些东西存储进仓库里面(内存)。变量var在正式运行之前,都赋值为undefined,function函数在运行之前,就是整个函数块

逐行解读

表达式=、+、-、*、/、++、--、!、%.....number()、参数都可以赋值

遇到重名的,只留下一个,变量和函数重名,函数优先级高于变量,只留下函数

函数调用(函数是一个作用域,遇到作用域都会按照先进行预解析,然后逐行解读的过程执行),先局部找参数,局部找不到就自下向上找(作用域链)

概念扯了一大段,估计初学者还是有点晕乎乎,老司机就可以提前下车了,接下来,咋们举几个小栗子,结合上面的理论,深入理解。

实践

例1:

alert(a); //error: a is not defined
a = 3;

分析:

预解析

上面说过,预解析时只会把var 、 function 、参数等存储起来,所以:

整个作用域没有找到var function 参数

逐行解读

预解析后,内存中存在a且被赋值了underfind整个变量,所有,代码执行过程中程序直接报错。

例2:

alert(a); //undefined
var a = 3;

分析:

预解析

上面说过,预解析时只会把var 、 function 、参数等存储起来,所以:

执行到第二行时,a 的值是未定义。

逐行解读

第一行:预解析后,内存中存在a且被赋值了underfined

例3:

alert(a);          // function a (){ alert(4); }
var a = 1;
alert(a);          // 1
function a (){ alert(2); }
alert(a);          // 1
var a = 3;    
alert(a);          // 3
function a (){ alert(4); }
alert(a);          // 3

分析:

域解析

上面说过,预解析时只会把var 、 function 、参数等存储起来,所以:

执行到第二行时,a 的值是未定义。

执行到第四行时,a 的值是函数本身,也就是function a(){alert(2);}。

执行到第六行时,a 的值还是第四行时的值,也就是function a(){alert(2);},因为函数的优先级比变量高。

执行到第八行时,a 的值就变成了function a(){alert(4);} ,因为当两个函数重名时,遵循代码从上往下执行。

逐行解读

预解析完成之后,就是代码逐行执行了,

第一行:会弹出function a(){alert(4);} ,因为预解析完成之后,被存进内存的a 的值就是function a(){alert(4);}

第二行:第二行里有表达式,a 被赋了一个新的值1 表达式会改变变量的值。表达式可以改变预解析的值。

第三行:a现在被赋值为1,所有会弹出1

第四行:只是函数的声明,并没有用到表达式,而且也没有函数的调用,所以不会改变a 的值。

第五行:因为a的值没有变化,所以还是1

第六行:使用了表达式,a 被赋了一个新的值3

第七行:会弹出3

第八行:函数的声明,不会改变a 的值。

第九行:a的值没有改变,所以还是3

通过上面的栗子,相信大家应该对变量作用域的预解析过程有一定的了解了,接下来,咋们再举几个函数作用域的栗子

例4:

var a=1;
function fn1(){
  alert(a); //undefined
  var a = 2;
}
fn1();
alert(a) //1

例5:

var a=1;
function fn1(a){
  alert(a); //1
  var a = 2;
}
fn1(a);
alert(a) //1

例6:

var a=1;
function fn1(a){
  alert(a); //1
  a = 2;
}
fn1(a);
alert(a) //1

例7:

var a=1;
function fn1(){
  alert(a); //1
  a = 2;
}
fn1(a);
alert(a) //2

这几个栗子想必不用在一步步分析吧,不过就一点小改动,可能结果就截然不同,所以,大家还是需要仔细琢磨下。

Javascript 相关文章推荐
jquery.ui.progressbar 中文文档
Nov 26 Javascript
js 键盘记录实现(兼容FireFox和IE)
Feb 07 Javascript
js中将URL中的参数提取出来作为对象的实现代码
Aug 16 Javascript
封装了一个js图片轮换效果的函数
Sep 28 Javascript
基于jquery的鼠标拖动效果代码
May 30 Javascript
使用javascript实现简单的选项卡切换
Jan 09 Javascript
JavaScript前补零操作实例
Mar 11 Javascript
JavaScript实现瀑布流以及加载效果
Feb 11 Javascript
微信小程序左滑删除效果的实现代码
Feb 20 Javascript
微信小程序实现页面跳转传值以及获取值的方法分析
Dec 18 Javascript
详解ES6语法之可迭代协议和迭代器协议
Jan 13 Javascript
vue-cli 引入jQuery,Bootstrap,popper的方法
Sep 03 jQuery
Vue使用枚举类型实现HTML下拉框步骤详解
Feb 05 #Javascript
jQuery实现动态显示select下拉列表数据的方法
Feb 05 #jQuery
详解vue静态资源打包中的坑与解决方案
Feb 05 #Javascript
理解Koa2中的async&await的用法
Feb 05 #Javascript
zTree 树插件实现全国五级地区点击后加载的示例
Feb 05 #Javascript
使用vue如何构建一个自动建站项目
Feb 05 #Javascript
在 webpack 中使用 ECharts的实例详解
Feb 05 #Javascript
You might like
无线电波是什么?它是怎样传输的?
2021/03/01 无线电
2014最热门的24个php类库汇总
2014/12/18 PHP
PHP使用HTML5 FileApi实现Ajax上传文件功能示例
2019/07/01 PHP
Js 刷新框架页的代码
2010/04/13 Javascript
url参数中有+、空格、=、%、&、#等特殊符号的问题解决
2013/05/15 Javascript
封装好的一个万能检测表单的方法
2015/01/21 Javascript
js控制文本框输入的字符类型方法汇总
2015/06/19 Javascript
基于AngularJS前端云组件最佳实践
2016/10/20 Javascript
关于在vue-cli中使用微信自动登录和分享的实例
2017/06/22 Javascript
js实现单张图片平移切换效果
2017/10/11 Javascript
Nginx 配置多站点vhost 的方法
2018/01/07 Javascript
详解开发react应用最好用的脚手架 create-react-app
2018/04/24 Javascript
解决nodejs的npm命令无反应的问题
2018/05/17 NodeJs
vue富文本框(插入文本、图片、视频)的使用及问题小结
2018/08/17 Javascript
angularjs实现对表单输入改变的监控(ng-change和watch两种方式)
2018/08/29 Javascript
jQuery实现侧边栏隐藏与显示的方法详解
2018/12/22 jQuery
17道题让你彻底理解JS中的类型转换
2019/08/08 Javascript
[52:29]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#3Secret VS OG第三局
2016/03/03 DOTA
[01:36]DOTA2完美大师赛趣味视频之与队友相处的十万个技巧
2017/11/19 DOTA
[02:33]DOTA2亚洲邀请赛趣味视频之吐真话筒
2018/03/31 DOTA
常用python数据类型转换函数总结
2014/03/11 Python
把MySQL表结构映射为Python中的对象的教程
2015/04/07 Python
简单实现python进度条脚本
2017/12/18 Python
python中利用zfill方法自动给数字前面补0
2018/04/10 Python
详解Django中间件执行顺序
2018/07/16 Python
Python实现带参数的用户验证功能装饰器示例
2018/12/14 Python
python框架django项目部署相关知识详解
2019/11/04 Python
python基本算法之实现归并排序(Merge sort)
2020/09/01 Python
台湾前三大B2C购物网站:MOMO购物网
2017/04/27 全球购物
应届毕业生求职信
2013/11/30 职场文书
企业文化口号
2014/06/12 职场文书
干部对照检查材料范文
2014/08/26 职场文书
反对四风自我剖析材料
2014/10/07 职场文书
2014小学语文教学工作总结
2014/12/17 职场文书
使用 Docker Compose 构建复杂的多容器App
2022/04/30 Servers
利用Redis实现点赞功能的示例代码
2022/06/28 Redis