详解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 相关文章推荐
保证JavaScript和Asp、Php等后端程序间传值编码统一
Apr 17 Javascript
document.getElementById方法在Firefox与IE中的区别
May 18 Javascript
js parseInt("08")未指定进位制问题
Jun 19 Javascript
关于Javascript模块化和命名空间管理的问题说明
Dec 06 Javascript
js调试系列 控制台命令行API使用方法
Jun 18 Javascript
javascript实现修改微信分享的标题内容等
Dec 11 Javascript
jscript读写二进制文件的方法
Apr 22 Javascript
jQuery的事件委托实例分析
Jul 15 Javascript
全面了解JavaScirpt 的垃圾(garbage collection)回收机制
Jul 11 Javascript
JavaScript每天必学之基础知识
Sep 17 Javascript
浅谈EasyUI常用控件的禁用方法
Nov 09 Javascript
Html5 js实现手风琴效果
Apr 17 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
JAVA/JSP学习系列之二
2006/10/09 PHP
php使用base64加密解密图片示例分享
2014/01/20 PHP
Laravel 4 初级教程之安装及入门
2014/10/30 PHP
PHP中获取文件创建日期、修改日期、访问时间的方法
2016/11/05 PHP
基于ThinkPHP5.0实现图片上传插件
2017/09/25 PHP
php 与 nginx 的处理方式及nginx与php-fpm通信的两种方式
2018/09/28 PHP
PHP设计模式之模板方法模式实例浅析
2018/12/20 PHP
关于php开启错误提示的总结
2019/09/24 PHP
javascript跟随滚动效果插件代码(javascript Follow Plugin)
2013/08/03 Javascript
jQuery中unwrap()方法用法实例
2015/01/16 Javascript
Javascript显示和隐藏ul列表的方法
2015/07/15 Javascript
Jquery跨域获得Json的简单实例
2016/05/18 Javascript
JavaScript 字符串常用操作小结(非常实用)
2016/11/30 Javascript
vue2.0 如何把子组件的数据传给父组件(推荐)
2018/01/15 Javascript
js/jquery遍历对象和数组的方法分析【forEach,map与each方法】
2019/02/27 jQuery
「中高级前端面试」JavaScript手写代码无敌秘籍(推荐)
2019/04/08 Javascript
vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略
2019/06/04 Javascript
Node.js中console.log()输出彩色字体的方法示例
2019/12/01 Javascript
手把手教您实现react异步加载高阶组件
2020/04/07 Javascript
基于aotu.js实现微信自动添加通讯录中的联系人功能
2020/05/28 Javascript
Javascript confirm多种使用方法解析
2020/09/25 Javascript
python字符串反转的四种方法详解
2019/12/02 Python
Python生态圈图像格式转换问题(推荐)
2019/12/02 Python
PyQt5高级界面控件之QTableWidget的具体使用方法
2020/02/23 Python
win7上tensorflow2.2.0安装成功 引用DLL load failed时找不到指定模块 tensorflow has no attribute xxx 解决方法
2020/05/20 Python
纯CSS绘制漂亮的圆形图案效果
2014/05/07 HTML / CSS
记一次高分屏下canvas模糊问题
2020/02/17 HTML / CSS
法国在线宠物店:zooplus.fr
2018/02/23 全球购物
美国农场鲜花速递:The Bouqs
2018/07/13 全球购物
美国一站式电动和手动工具商店:International Tool
2020/11/26 全球购物
应届生会计电算化求职信
2013/10/03 职场文书
光电信息专业应届生求职信
2013/10/07 职场文书
护士自我鉴定
2013/10/23 职场文书
幸福家庭事迹材料
2014/02/03 职场文书
天地会口号
2014/06/17 职场文书
房屋登记授权委托书范本
2014/10/09 职场文书