详解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 相关文章推荐
兼容IE、FireFox、Chrome等浏览器的xml处理函数js代码
Nov 30 Javascript
js实现无需数据库的县级以上联动行政区域下拉控件
Aug 14 Javascript
javascript中一些util方法汇总
Jun 10 Javascript
学习JavaScript设计模式(策略模式)
Nov 26 Javascript
基于JavaScript实现根据手机定位获取当前具体位置(X省X市X县X街道X号)
Dec 29 Javascript
Javascript中匿名函数的调用与写法实例详解(多种)
Jan 26 Javascript
微信小程序 实现拖拽事件监听实例详解
Nov 16 Javascript
原生JS实现跑马灯效果
Feb 20 Javascript
原生JavaScript实现的简单省市县三级联动功能示例
May 27 Javascript
Element-UI Table组件上添加列拖拽效果实现方法
Apr 14 Javascript
详解Webpack抽离第三方类库以及common解决方案
Mar 30 Javascript
JS变量提升原理与用法实例浅析
May 22 Javascript
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
使用php判断服务器是否支持Gzip压缩功能
2013/09/24 PHP
制作安全性高的PHP网站的几个实用要点
2014/12/30 PHP
smarty学习笔记之常见代码段用法总结
2016/03/19 PHP
PHP实现15位身份证号转18位的方法分析
2019/10/16 PHP
JavaScript面向对象之体会[总结]
2008/11/13 Javascript
js设置cookie过期及清除浏览器对应名称的cookie
2013/10/24 Javascript
jQuery级联操作绑定事件实例
2014/09/02 Javascript
js淡入淡出的图片轮播效果代码分享
2015/08/24 Javascript
JavaScript中Date对象的常用方法示例
2015/10/24 Javascript
在bootstrap中实现轮播图实例代码
2017/06/11 Javascript
基于jQuery和CSS3实现APPLE TV海报视差效果
2017/06/16 jQuery
jQuery实现table中两列CheckBox只能选中一个的示例
2017/09/22 jQuery
vue的keep-alive中使用EventBus的方法
2019/04/23 Javascript
详解Vue+ElementUI从零开始搭建自己的网站(一、环境搭建)
2019/04/30 Javascript
微信小程序代码上传、审核发布小程序
2019/05/18 Javascript
Vue实现导航栏点击当前标签变色功能
2020/08/19 Javascript
Vue v-text指令简单使用方法示例
2019/09/19 Javascript
javascript设计模式 ? 组合模式原理与应用实例分析
2020/04/14 Javascript
JavaScript canvas实现雨滴特效
2021/01/10 Javascript
node.js 基于 STMP 协议和 EWS 协议发送邮件
2021/02/14 Javascript
Python GUI学习之登录系统界面篇
2019/08/21 Python
python实现UDP协议下的文件传输
2020/03/20 Python
django实现HttpResponse返回json数据为中文
2020/03/27 Python
解决pyPdf和pyPdf2在合并pdf时出现异常的问题
2020/04/03 Python
Python3+RIDE+RobotFramework自动化测试框架搭建过程详解
2020/09/23 Python
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点
2013/01/09 HTML / CSS
美国办公用品折扣网站:Shoplet.com
2019/11/24 全球购物
阿联酋优惠券服务:Living Kool
2019/12/12 全球购物
大学班长的职责
2014/01/27 职场文书
委托协议书范本
2014/04/22 职场文书
公司离职证明范本
2014/10/17 职场文书
初中家长评语大全
2014/12/26 职场文书
关于上班时间调整的通知
2015/04/23 职场文书
复兴之路展览观后感
2015/06/02 职场文书
最新最全的手机号验证正则表达式
2022/02/24 Javascript
Golang并发工具Singleflight
2022/05/06 Golang