js作用域其二:预解析
解析机制
JavaScript是一门解释型的语言 , 想要运行js代码需要两个阶段
- 编译阶段: 编译阶段就是我们常说的JavaScript预解析(预处理)阶段,在这个阶段JavaScript解释器将完成把JavaScript脚本代码转换到字节码
- 执行阶段: 在编译阶段JavaScript解释器借助执行环境把字节码生成机械码,并从上到下按顺序执行
预解析时做什么
var , function声明的变量提升
首先,创建一个当前执行环境下的活动对象,然后将用 var 声明的变量设置为活动对象的属性(也就是将其添加到活动对象当中)并将其赋值为undefined,然后将 function 定义的函数 也添加到活动对象当中
1 |
if( false ){
|
var定义的aa,bb以及function定义的AA(),BB()都会被变量提升到window对象下面 提升后等同于如下代码:
1 |
var aa; |
注: 不是用var 定义的变量具有全局性, 但是并不会被提升, 只有在第一次执行到时才会出现在全局作用域中
函数声明与函数表达式在预解析的区别
首先,我们知道解析器会对function定义的函数(也就是函数声明)在代码开始执行之前对其实行函数声明提升(function declaration hoisting),所以在函数声明之前调用该函数是不会在执行期间报错,但是函数表达式不同,函数表达式用 var 声明,也就是说解析器会对其变量提升,并对其赋值为undefined,然后在执行期间,等到执行到该var 变量的时候再将其变量指向一个function函数,所以在函数表达式之前执行该函数是会报错的。
1 |
AA(); |
AA();不会报错,因为是以function的变量提升,BB()会报错,因为是以var的变量提升,提升后代码等同于如下:
1 |
function (){};
|
注意: 函数声明提升以后并不会执行内部的代码, 在其内的变量声明也不会起作用, 而是等到函数第一次被调用时才会执行 如:
1 |
var AA = function(){
|
单独这一段代码并不会起作用, 只有执行:
1 |
AA(); // 输出 AA |
function 覆盖
若定义了两个同名的函数,则在预解析期间后面一个会覆盖签名一个
大专栏 js作用域其二:预解析ass="gutter">
1 |
AA(); // 输出 I am AA_2; |
提升后其代码等同于如下:
1 |
function AA(){
|
可以看到这是正常的函数声明覆盖
预解析把变量或函数解析到其运行时的环境中
解析器将变量提升并不是将所有的变量都提升到window对象下面,其提升的原则是提升到变量运行的环境(变量生效的词法作用域)顶端
1 |
aa = "I am aa"; |
这里 aa 被变量提升,但是aa 没有被变量提升到 window下面,而是被提升到其运行的环境 (function(){ })() 中去,也就是等同于
1 |
aa = "I am aa"; |
JavaScript“预解析”分段进行
所谓分段进行是按照< script >标签来分块进行预解析
1 |
<script> |
上面例子说明function函数声明是分块的,然而至于var变量的提升经过反复验证是不分块的( 此处如有不同意见请指教 )
参考
javascript解析机制——预解析
本文是在此篇博客的基础上进行了修改与扩充
js作用域其二:预解析的更多相关文章
- JS作用域概念-预解析规则
// 作用域: // 域:空间.范围.区域…… // 作用:读.写 script 全局变量.全局函数 自上而下 函数 由里到外 {} 浏览器: “JS解析器” 1)“找一些东西” :var funct ...
- 14 (H5*) JS第4天 函数、作用域、预解析
目录 1:函数的其他定义 2:函数作为参数 3:函数作为返回值 4:作用域 5:作用域链 6:预解析 7:预解析分段 复习 <script> /* * 复习: * 函数:把一些重复的代码封 ...
- JavaScript (四) js的基本语法 - - 函数练习、arguments、函数定义、作用域、预解析
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.函数练习 1.求最值 // - 求2个数中的最大值 function getMax(num1, nu ...
- JS基础研语法---函数基础总结---定义、作用、参数、返回值、arguments伪数组、作用域、预解析
函数: 把一些重复的代码封装在一个地方,在需要的时候直接调用这个地方的代码就可以了 函数作用: 代码重用 函数的参数: 形参:函数定义的时候,函数名字后面的小括号里的变量 实参:函数调用的时候,函数名 ...
- javascript作用域、预解析笔记
1.作用域 一般情况下,一段代码中所用到的名字并不总是有效可用的, 而限定这个名字(变量)的可用性的代码范围就是这个名字的作用域,可用有效的减少变量名冲突 2.js的作用域(e ...
- javascript里面的闭包,作用域,预解析
函数的作用域 1.全局变量=公用卫生间 2.局部变量=次卧卫生间 局部变量 全局无法使用 局部声明变量不加var的话就变成全局变量(不推荐使用) 3.闭包=次卧的可以用自己的卫生间 ...
- JS中的预解析
js预解析对于很多学习web前端开发的新手们很困扰,总是很难搞懂到底是个什么东西,今天零度就为大家简单的分析一下,争取让大家都明白! 首先,看一下下面的代码: alert(a); var a = 1; ...
- JS基础语法---预解析
预解析:就是在解析代码之前 1. 预解析做什么事? 把变量的声明提前了----提前到当前所在的作用域的最上面 函数的声明也会被提前---提前到当前所在的作用域的最上面 举例: function ...
- 函数(定义、参数、return、变量、作用域、预解析)
一.函数定义 1.方式一 function 函数名(参数){ 函数体 }——————函数声明的方法 function fn(a){ console.log(a); }: 2.方式二 ...
随机推荐
- Python笔记_第一篇_面向过程_第一部分_5.Python数据类型之元组类型(tuple)
元组!在Python中元组是属于列表的一种延伸,也是一种有序集合,成为一种只读列表,即数据可以被查找,不能被修改,列表的切片操作同样适用于元组. 特点:1. 与列表非常相似. 2. 一旦初始化就不能修 ...
- Covisibility Graph
在Orb-Slam中有三个地图分别是Covisibility Graph,Spanning Graph,以及Essential Graph,它们三个分别是什么意思呢? 首先,图优化是目前视觉SLAM里 ...
- Python执行JS -- PyExecJS库
pip install PyExecJS 查看执行JS的环境 print(execjs.get().name) 返回值:JScript windows 默认执行JS的环境 返回值:Node.js (V ...
- 吴裕雄--天生自然 PYTHON3开发学习:字典
dict = {'} dict1 = { 'abc': 456 } dict2 = { 'abc': 123, 98.6: 37 } dict = {'Name': 'Runoob', 'Age': ...
- debian8.8安装sougou输入法
传送门:http://www.cnblogs.com/ligongzi/p/6137601.html 亲测可用
- mysql批量删除报1064原因
DELETE FROM table_name t where t......; 报1064 错误,原因MySQL 中delete 语句不能给表名起别名. 另外.如果记录不存在,delete from ...
- Opencv笔记(十九)——直方图(一)
直方图概念 图像的构成是有像素点构成的,每个像素点的值代表着该点的颜色(灰度图或者彩色图).所谓直方图就是对图像的中的这些像素点的值进行统计,得到一个统一的整体的灰度概念.一般情况下直方图都是灰度图像 ...
- 【Java杂货铺】用Security做权限极简入门
原来大多数单体项目都是用的shiro,随着分布式的逐渐普及以及与Spring的天生自然的结合.Spring Security安全框架越受大家的青睐.本文会教你用SpringSecurity设计单项目的 ...
- 802.11X
LSW1; interface Vlanif100 ip address 192.168.121.2 255.255.255.0连接云的地址 interface GigabitEthernet0/0/ ...
- Cantor表(模拟)
链接:https://ac.nowcoder.com/acm/contest/1069/I来源:牛客网 题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一 ...