详解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 相关文章推荐
分享一个自己写的table表格排序js插件(高效简洁)
Oct 29 Javascript
jquery实现网站超链接和图片提示效果
Mar 21 Javascript
js实现键盘操作实现div的移动或改变的原理及代码
Jun 23 Javascript
jquery checkbox 勾选的bug问题解决方案与分析
Nov 13 Javascript
JS控制网页动态生成任意行列数表格的方法
Mar 09 Javascript
JavaScript实现的伸展收缩型菜单代码
Oct 14 Javascript
一个例子轻松学会Vue.js
Jan 02 Javascript
layui实现文件或图片上传记录
Aug 28 Javascript
利用JS如何获取form表单数据
Dec 19 Javascript
Vue-cli3生成的Vue项目加载Mxgraph方法示例
May 31 Javascript
vue 路由meta 设置导航隐藏与显示功能的示例代码
Sep 04 Javascript
vue中如何添加百度统计代码
Dec 19 Vue.js
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/02 无线电
MySQL的FIND_IN_SET函数使用方法分享
2012/03/27 PHP
php模仿asp Application对象在线人数统计实现方法
2015/01/04 PHP
Linux系统下PHP-FPM的安装和配置教程
2015/08/17 PHP
PHP程序员不应该忽略的3点
2015/10/09 PHP
php实现遍历多维数组的方法
2015/11/25 PHP
Joomla简单判断用户是否登录的方法
2016/05/04 PHP
laravel框架之数据库查出来的对象实现转化为数组
2019/10/23 PHP
PHP数组array类常见操作示例
2020/05/15 PHP
jquery 表单下所有元素的隐藏
2009/07/25 Javascript
ajax的hide隐藏问题解决方法
2012/12/11 Javascript
深入探讨JavaScript String对象
2015/03/09 Javascript
JS实现的Select三级下拉菜单代码
2015/08/20 Javascript
JS实现的通用表单验证插件完整实例
2015/08/20 Javascript
JavaScript实现字符串与日期的互相转换及日期的格式化
2016/03/07 Javascript
JavaScript性能优化总结之加载与执行
2016/08/11 Javascript
Angular模版驱动表单的使用总结
2018/05/05 Javascript
使用vue-cli(vue脚手架)快速搭建项目的方法
2018/05/21 Javascript
关于vue的语法规则检测报错问题的解决
2018/05/21 Javascript
JS获取月的第几周和年的第几周实例代码
2018/12/05 Javascript
jQuery实现的别踩白块小游戏完整示例
2019/01/07 jQuery
Vue实现数据表格合并列rowspan效果
2020/11/30 Javascript
使用JavaScript获取扫码枪扫描得到的条形码的思路代码详解
2020/06/10 Javascript
Python内置的字符串处理函数详细整理(覆盖日常所用)
2014/08/19 Python
Python while、for、生成器、列表推导等语句的执行效率测试
2015/06/03 Python
Python实现比较两个列表(list)范围
2015/06/12 Python
python使用psutil模块获取系统状态
2016/08/27 Python
pip安装py_zipkin时提示的SSL问题对应
2018/12/29 Python
python批量处理文件或文件夹
2020/07/28 Python
美国波西米亚风格服装品牌:Show Me Your Mumu
2018/01/05 全球购物
医学专业毕业生个人的求职信
2013/12/04 职场文书
全国税务系统先进集体事迹材料
2014/05/19 职场文书
物业管理专业自荐信
2014/07/01 职场文书
企业群众路线教育实践活动心得体会
2014/11/03 职场文书
会计简历自我评价
2015/03/10 职场文书
手把手教你怎么用Python实现zip文件密码的破解
2021/05/27 Python