文章目錄

解析机制

JavaScript是一门解释型的语言 , 想要运行js代码需要两个阶段

  1. 编译阶段: 编译阶段就是我们常说的JavaScript预解析(预处理)阶段,在这个阶段JavaScript解释器将完成把JavaScript脚本代码转换到字节码
  2. 执行阶段: 在编译阶段JavaScript解释器借助执行环境把字节码生成机械码,并从上到下按顺序执行

预解析时做什么

var , function声明的变量提升

  首先,创建一个当前执行环境下的活动对象,然后将用 var 声明的变量设置为活动对象的属性(也就是将其添加到活动对象当中)并将其赋值为undefined,然后将 function 定义的函数 也添加到活动对象当中

1
2
3
4
5
6
7
if( false ){
var aa = 20;
var bb = 30;
} function (){};
function BB(){};

var定义的aa,bb以及function定义的AA(),BB()都会被变量提升到window对象下面 提升后等同于如下代码:

1
2
3
4
5
6
7
8
var aa;
var bb;
function (){};
function BB(){};
if( false ){
aa = 20;
bb = 30;
}

注: 不是用var 定义的变量具有全局性, 但是并不会被提升, 只有在第一次执行到时才会出现在全局作用域中

函数声明与函数表达式在预解析的区别

  首先,我们知道解析器会对function定义的函数(也就是函数声明)在代码开始执行之前对其实行函数声明提升(function declaration hoisting),所以在函数声明之前调用该函数是不会在执行期间报错,但是函数表达式不同,函数表达式用 var 声明,也就是说解析器会对其变量提升,并对其赋值为undefined,然后在执行期间,等到执行到该var 变量的时候再将其变量指向一个function函数,所以在函数表达式之前执行该函数是会报错的。

1
2
3
4
5
AA();
function (){}; BB();
var BB = function(){};

AA();不会报错,因为是以function的变量提升,BB()会报错,因为是以var的变量提升,提升后代码等同于如下:

1
2
3
4
5
6
function (){};
var BB; AA();
BB();
BB = function(){};

注意: 函数声明提升以后并不会执行内部的代码, 在其内的变量声明也不会起作用, 而是等到函数第一次被调用时才会执行 如:

1
2
3
4
5
6
7
var AA = function(){
console.log(' AA ');
} function BB(){
console.log(' BB ');
}

单独这一段代码并不会起作用, 只有执行:

1
2
AA(); // 输出 AA
BB(); //输出 BB

function 覆盖

 若定义了两个同名的函数,则在预解析期间后面一个会覆盖签名一个

大专栏  js作用域其二:预解析ass="gutter">
1
2
3
4
5
6
7
8
9
AA();   // 输出 I am AA_2;
function (){
console.log('I am AA_1');
}; AA(); // 输出 I am AA_2;
function AA(){
console.log('I am AA_2');
}

提升后其代码等同于如下:

1
2
3
4
5
6
7
8
9
10
function AA(){
console.log('I am AA_1');
} function AA(){
console.log('I am AA_2');
} AA();
AA();

可以看到这是正常的函数声明覆盖

预解析把变量或函数解析到其运行时的环境中

解析器将变量提升并不是将所有的变量都提升到window对象下面,其提升的原则是提升到变量运行的环境(变量生效的词法作用域)顶端

1
2
3
4
5
6
7
aa = "I am aa";
function AA(){
console.log(aa); // 输出 aa 是 undefined
var aa = "I am aa in a function";
console.log(aa); //输出 aa 是 I am aa in a function
}
AA();

这里 aa 被变量提升,但是aa 没有被变量提升到 window下面,而是被提升到其运行的环境 (function(){ })() 中去,也就是等同于

1
2
3
4
5
6
7
8
aa = "I am aa";
function AA(){
var aa;
console.log(aa); // 输出 aa 是 undefined
aa = "I am aa in a function";
console.log(aa); //输出 aa 是 I am aa in a function
}
AA();

JavaScript“预解析”分段进行

所谓分段进行是按照< script >标签来分块进行预解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
AA(); // 输出 AA2;
function AA(){
console.log('AA1');
} function AA(){
console.log('AA2');
}
</script> <script>
function AA(){
console.log('AA3');
}
</script>

上面例子说明function函数声明是分块的,然而至于var变量的提升经过反复验证是不分块的( 此处如有不同意见请指教 )

参考

javascript解析机制——预解析
本文是在此篇博客的基础上进行了修改与扩充

js作用域其二:预解析的更多相关文章

  1. JS作用域概念-预解析规则

    // 作用域: // 域:空间.范围.区域…… // 作用:读.写 script 全局变量.全局函数 自上而下 函数 由里到外 {} 浏览器: “JS解析器” 1)“找一些东西” :var funct ...

  2. 14 (H5*) JS第4天 函数、作用域、预解析

    目录 1:函数的其他定义 2:函数作为参数 3:函数作为返回值 4:作用域 5:作用域链 6:预解析 7:预解析分段 复习 <script> /* * 复习: * 函数:把一些重复的代码封 ...

  3. JavaScript (四) js的基本语法 - - 函数练习、arguments、函数定义、作用域、预解析

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.函数练习 1.求最值 // - 求2个数中的最大值 function getMax(num1, nu ...

  4. JS基础研语法---函数基础总结---定义、作用、参数、返回值、arguments伪数组、作用域、预解析

    函数: 把一些重复的代码封装在一个地方,在需要的时候直接调用这个地方的代码就可以了 函数作用: 代码重用 函数的参数: 形参:函数定义的时候,函数名字后面的小括号里的变量 实参:函数调用的时候,函数名 ...

  5. javascript作用域、预解析笔记

    1.作用域     一般情况下,一段代码中所用到的名字并不总是有效可用的,     而限定这个名字(变量)的可用性的代码范围就是这个名字的作用域,可用有效的减少变量名冲突     2.js的作用域(e ...

  6. javascript里面的闭包,作用域,预解析

    函数的作用域 1.全局变量=公用卫生间 2.局部变量=次卧卫生间      局部变量 全局无法使用      局部声明变量不加var的话就变成全局变量(不推荐使用) 3.闭包=次卧的可以用自己的卫生间 ...

  7. JS中的预解析

    js预解析对于很多学习web前端开发的新手们很困扰,总是很难搞懂到底是个什么东西,今天零度就为大家简单的分析一下,争取让大家都明白! 首先,看一下下面的代码: alert(a); var a = 1; ...

  8. JS基础语法---预解析

    预解析:就是在解析代码之前   1. 预解析做什么事? 把变量的声明提前了----提前到当前所在的作用域的最上面 函数的声明也会被提前---提前到当前所在的作用域的最上面   举例: function ...

  9. 函数(定义、参数、return、变量、作用域、预解析)

    一.函数定义 1.方式一       function 函数名(参数){  函数体  }——————函数声明的方法 function fn(a){ console.log(a); }: 2.方式二  ...

随机推荐

  1. psi 函数计算

    scipy.special.psi odps中不支持 scipy.special.psi,需要改写 基于 chebyshev_polynomial https://people.sc.fsu.edu/ ...

  2. 拾起HTML+CSS的一天

    今天在w3school看了下HTML5和CSS3的新特性. 本来觉得自己对CSS方面基础还挺有把握的,就之前自学都是跳过这个模块的,但经过昨天会友的面试,感觉自己好像太忽视基础了,很多基本的东西很模糊 ...

  3. Opencv笔记(十)——卷积基础

    卷积 什么是二维卷积呢?看下面一张图就一目了然:         卷积就是循环对图像跟一个核逐个元素相乘再求和得到另外一副图像的操作,比如结果图中第一个元素5是怎么算的呢?原图中3×3的区域与3×3的 ...

  4. G - 旅行的意义(概率DP) (DAG图的概率与期望)

    为什么有人永远渴望旅行,或许就因为,巧合和温暖会在下一秒蜂拥而至吧. 一直想去旅游的天天决定在即将到来的五一假期中安排一场环游世界的旅行.为此,他已经提前查阅了很多资料,并准备画一张旅游路线图.天天先 ...

  5. Eclipse中配置使用本地schema或dtd文件

    问题:在设备不能正常联网的情况下,无法获取到网络上的 dtd 或 schema,编写配置文件的 XML 文档就没有了提示功能. 一般情况下,下载的 Jar 包或者 Zip 包中都会包含需要的 sche ...

  6. the least-squares criterion|Sxx|Sxy|Syy|Regression Equation|Outliers|Influential Observations|curvilinear regression|linear regression

    4.2 The Regression Equation Because we could draw many different lines through the cluster of data p ...

  7. 西甲官方APP承认监听球迷,或给国内应用带来新思路

    在此前,一般巨头或者官方推出的产品.应用等总是值得信赖的.出问题的话一般都是"不可抗拒的外力因素",比如被黑客攻破导致用户隐私被窃取等.但自从Facebook的用户隐私泄露丑闻被曝 ...

  8. 谈谈有关 Python 的GIL 和 互斥锁

    转载:https://blog.csdn.net/Amberdreams/article/details/81274217 有 Python 开发经验的人也许听说过这样一句话:Python 不能充分利 ...

  9. Selenium处理alert/confirm/prompt提示框

    About 回到顶部 重新认识alert首先,不是所有的alert都能叫做alert框.JavaScript中,关于消息提示框的方法有三个(虽然都跟alert差不多): alert(message)方 ...

  10. operator和if结构

    1.比较运算符:>,<,==,!=,>=,<= 注意:所有比较运算符的结果都是布尔值举例: 123456789 print(100>10) print(100<10 ...