先有鸡还是先有蛋?

直觉上会认为 JavaScript 代码在执行时是由上到下一行一行执行的。但实际上这并不完全正确,我们来看下面2个例子

//例子1:
a = 2;
var a;
console.log( a );  //2//例子2
console.log(a); //undefined
var a = 2;

通过这2个例子,我来深入的了解一下。到底是声明(蛋)在前,还是赋值(鸡)在前?

编译器解析规则

咱们要先知道,编译器运行代码,分为2个阶段,一个预编译阶段,一个是运行阶段;

一、变量提升

可以来看一下 var a = 2这个表达式,可能咱们认为这是一个声明,但是实际上javascript将其分为2个声明,var a 和 a  = 2;

第一个定义声明在编译阶段,第二个赋值声明在运行阶段;

a = 2;
var a;
console.log(a);变成了下面这样var a = undefined;
a = 2;
console.log(a)

打个比方,这个过程就好像变量和函数声明从它们在代码中出现的位置被“移动” 到了最上面。这个过程就叫作提升。换句话说,先有蛋(声明)后有鸡(赋值)。

    二、函数提升

下面来看一下函数,函数声明也会进行函数提升

foo();
function foo() { console.log( a ); // undefinedvar a = 2;
}函数和变量提升之后就变成下面的function foo() {var a; console.log( a ); // undefined a = 2;
}
foo();

有一点需要注意,就是函数声明会进行,函数提升,但是函数表达式并不会进行函数提升

foo(); // 不是 ReferenceError, 而是 TypeError!
var foo = function bar() { // ...
};这个函数表达式其实就是变量提升的变化var foo = undefined;
foo();  //不是 ReferenceError, 而是 TypeError!
foo = function bar() { // ...
};

      三、函数优先

    foo(); // 1var foo;function foo() { console.log( 1 ); }foo = function() { console.log( 2 );};/************分析阶段******************************// 编译阶段var foo = undefined;foo = foo() { console.log( 1 ); }// 运行阶段foo(); //1foo = function() {console.log(2);}

当有变量声明和函数声明的变量名称相同时,根据函数优先原则,函数会覆盖变量;

下面这种情况,咱们在开发的时候,应该尽量避免。

下面我来总结一下预编译和变量提升:

1、js代码的运行会分为2个步骤,预编译和运行(执行)阶段,预编译看下面的总结,执行就是从上往下一行一行的运行;

2、找文中的var 和 function;将var的变量和function声明的变量提升到顶部,var的初始化为undefined,function的初始化为函数。

3、var的变量和函数的变量名称相同的时候,根据函数优先的原则,函数会覆盖之前var变量;

4、var相同的名称,后续声明会忽略;function相同的名称,后续声明会覆盖;

5、函数定义var foo = function(){} 就当 变量来处理;也就是文中所说的函数声明会提升,但是函数表达式不会提升

6、在函数内部的预编译,还是用上面总结的方法就好了;

7、开心的执行,拿到想要的结果,祝你进阶成功!!!

参考:你不知道的js上册

github进阶仓库,欢迎start

原创不易,自由转载,保留出处!!!

编译器预编译与变量提升相关推荐

  1. JS----预编译及变量提升详解

    前言 JS属于解释型语言,在执行过程中顺序执行,但是会分块先预编译然后才执行.因此在JS中存在一种变量提升的现象.搞懂预编译环节,变量提升自然而然也就懂了.本文讲围绕以下几点进行介绍(变量提升会穿插在 ...

  2. 5单个编译总会编译全部_5分钟读懂JavaScript预编译

    大家都知道JavaScript是解释型语言,既然是解释型语言,就是编译一行,执行一行,那又何来预编译一说呢?脚本执行js引擎都做了什么呢?今天我们就来看看吧. 1-JavaScript运行三部曲 语法 ...

  3. JavaScript 变量提升的作用

    文章目录 前言 预解析时期 正式执行时期 一.举例 1. 函数提升-求以下代码执行结果 2. 函数提升-求以下代码执行结果 3.函数提升-求以下代码的结果 4.变量提升-求以下代码的结果 5.clas ...

  4. JavaScript中函数作用域之精辟,函数原理的浅入深出,及程序执行预编译之通天编译???

    1.程序执行的前一刻会先将代码预编译一遍,如果有语法错误则直接终止程序运行 //预编译之通天编译 --> 在执行的前一刻,会把文件通天扫描一遍 /** //预编译 函数整体提升(即函数会放到程序 ...

  5. iOS项目预处理器环境变量设置

    preprocessor macro 预处理器宏 1.系统默认有两个预处理器环境,一个是DEBUG 一个是 RELEASE 都是大写. 2. 测试环境为0 可以进行log日志打印等  测试环境内存分配 ...

  6. js中立即执行函数会预编译吗_js变量提升和函数提升

    把变量提升函数提升拿出来讲,一看就知道是老前端搬砖工了,其实这些js的基础本质的东西,很有必要去了解,可以活跃思维,而且可以在研究这个的过程中,找到当初设计这门语言的人的想法,然后让自己不仅仅是对这个 ...

  7. JavaScript专题(一)变量提升与预编译,一起去发现Js华丽的暗箱操作

    JavaScript之变量与函数提升 相信阅读完<前端进阶系列>的朋友们已经对Js中经典的知识点有所了解.本系列的第一篇选择了一个值得讨论的问题--变量提升,我们会从遇到问题.分析问题.解 ...

  8. 【Web前端培训】预解析(变量提升)

    今天千锋小编为大家介绍一下一下JavaScript中的预解析(变量提升).从什么是预解析及变量的预解析和函数的预解析及加载流程进行学习(注意:我们这里说的ES5中的预解析). 什么是解析 首先代码执行 ...

  9. [EF4] CompiledQuery预编译性能提升 + 数据载入之大彻大悟

     //实验证明使用预编译后,对于需要[多次查询]的语句,可以提升到于ado.net几乎相同的性能         private static readonly Func<mydbEntitie ...

  10. 预编译头文件来自编译器的早期版本_Debug

    1.报错形式 用Visual Studio2010 编写C++程序,编译出现错误: 预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反) 2.解决方法 3.原因分析 ...

最新文章

  1. 在C++中使用LLVM的JIT功能进行代码优化:Optimization passes--PassManagerBuilder
  2. 什么猫咪最受欢迎?Python爬取全网猫咪图片,哪一款是你最爱的
  3. php margin参数,margin参数简单介绍_html/css_WEB-ITnose
  4. C# 学习笔记(14)自己的串口助手----多行发送
  5. Python核心编程读笔 8: 文件和输入输出
  6. Git安装及配置5分钟快速教程
  7. 再次参加(第七届)商学院徒步戈壁挑战赛,赋词几首
  8. Service rootservice does not have a SELinux domain defined
  9. HTML 表单和输入
  10. 【clickhouse】Code: 135. DB::Exception: Received from xxx:9000. DB::Exception: Indices in strings are
  11. c/c++ 标准库 string
  12. python代码修改nginx配置_生产环境部署python代码(django+uwsgi+nginx)
  13. Splice Beatmaker for Mac(音乐节拍工具)
  14. 电子信息工程专业打工人的蓝桥杯嵌入式竞赛时记
  15. 360安全卫士默认浏览器设置 360默认浏览器设置 锁定浏览器
  16. [wechart] 微信小程序使用粘性定位position: sticky的注意事项(避坑)
  17. Dynamics AX 2009 Trainning
  18. 利用python批量将excel中文翻译成英文
  19. Python3.7+Robot Framework 打开ride.py无界面
  20. Java线程池几个参数的理解

热门文章

  1. docker容器无法删除——状态Dead
  2. Scrum Meeting 2 (2016-12-19 Mon)
  3. display:block jquery.sort()
  4. Django 一些少用却很实用的orm查询方法
  5. Django 路由系统
  6. golang学习笔记14 golang substring 截取字符串
  7. JMeter基础教程1:若隐若现的参数化
  8. CODE ---代码助手 (保存代码、搜代码、生成网页、自由界面)
  9. [转载]Linux shell中的竖线(|)——管道符号
  10. 转:KVC与KVO机制