带var关键字预解释

让我们先看下这段代码执行的结果:

代码如下:
alert(n);//弹出undefined
var n = 10;

弹出的结果是undefined,为何不是10?让我们再看下面这段代码执行的结果:

代码如下:
alert(n);
n = 10;

运行报如下错误:

为何这次会报错,原因是代码在运行的时候,没有声明这个变量n;通过这两段代码的比较,我们发现带var关键字和不带var关键字声明的变量是有区别的,带var声明的变量在代码执行之前,似乎浏览器已经给了它们一个初始值undefined,因此我们将代码执行前,浏览器引擎自动扫描带var关键字和带function关键字(后面会提到)声明的变量和定义的函数的这个过程称为预解释。

带function关键字预解释

让我们看下如下代码执行的结果:

代码如下:
fn();//弹出hello
function fn(){
    alert('hello');
}

执行结果弹出hello,fn能够正常执行,原因是在代码执行前fn被预解释了,在预解释时已经将fn定义(defined)了,我们又有疑问了,为何第一段代码执行结果不弹出10,而是undefined,再次引入了另一个概念JavaScript中的声明和定义。

JavaScript中的声明(declare)和定义(defined)

我们通常用var关键来声明变量,用function关键字来定义函数,只不过function关键字声明和定义函数是同时执行的,而var它只能声明变量,并不具备定义的功能。

如下是用var关键字声明的变量:

代码如下:
var n;//声明了一个变量n
var m = 10;//声明了一个变量m,并且将10赋值给它

如下是用function关键字定义的函数:

代码如下:
//定义了一个函数fn
function fn(){
    alert('hello');
}

带var关键字和带function关键字预解释的区别

其实它俩的区别就是带var关键字预解释时只预解释声明部分(因为它本身不具备定义的能力),而带function关键字在预解释时声明和定义同时被预解释。这时我们再回头分析下第一段代码,分析如下:

无节操(坑爹)的预解释

为何说它无节操,请看下面的代码(火狐除外):

代码如下:
alert(n);
fn();
if(false) {
    var n = 10;
    function fn(){
        alert('hello');
    }
}

第一行代码执行会弹出undefined,第二行代码执行会弹出hello;是因为n和fn在代码执行前被预解释了,即使if条件判断为false,执着的浏览器引擎也会将带var关键字声明的变量n和带function关键定义的fn扫描到。

*预解释忽略重新声明,不忽略重新定义

这个地方因为相对比较绕而且不太好理解,所以加了一个星号,请看如下代码:

代码如下:
alert(n);
var n = 10;
var n = 9;
var n;
alert(n);

这段代码执行结果是什么,我们来分析一下:

继续上代码,请分析如下执行结果:

代码如下:
fn();
function fn() {
    alert('1');
}
fn();
function fn() {
    alert('2');
}
fn();

代码分析图如下:

带function定义的函数预解释分析

总结:

本篇博文用了大篇幅代码和截图对JavaScript中预解释作了概述,纵观各种书籍对预解释的描述甚少,其实平时在工作中使用的场景也并不多,遗憾的是预解释是各大公司面试题必考。在刚开始接触它的时候,感觉它总是不按照常理写代码,但是有些时候却能够正常运行并不会报错,当然这也增加了我们对它神秘感的探索,也让我们进一步了解浏览器引擎是怎么解释执行我们的代码。特此在后面的博文中我会拿几道经典的案例来综合分析它,再次感谢大家的支持!

扒一扒JavaScript 预解释的更多相关文章

  1. JavaScript预解释是一种毫无节操的机制

    前言 JavaScript是一门解释型的语言 , 想要运行JavaScript代码需要两个阶段 编译阶段: 编译阶段就是我们常说的JavaScript预解释(预处理)阶段,在这个阶段JavaScrip ...

  2. javascript预解释中的机制

    预解释是一种毫无节操的机制(自从学了预解释,从此节操是路人) in:‘num’ in window 判断num是否为window这个对象的一个属性,是的话返回true,不是返回false 1.预解释的 ...

  3. JavaScript提高篇之预解释作用域以及this原理及其应用

    1.预解释 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  4. 课程笔记:——javascript中的预解释2

    in:检测某一个属性是否属于这个对象(既可以检测私有的属性,也可以检测公有的属性) --> attr in obj 1.不管条件是否成立,在预解释的时候,判断体中的带var和function的都 ...

  5. 课程笔记:——Javascript 中的预解释1

    1.预解释(变量提升):在当前作用域下,JS代码执行之前,浏览器首先会把所有带var和function关键字的进行提前的声明或者定义var num = 12;声明(declare): var num; ...

  6. 关于javascript中私有作用域的预解释

    1.如何区分私有变量还是全局变量 1).在全局作用域下声明(预解释的时候)的变量是全局变量 2).在“私有作用域中声明的变量”和“函数的形参”都是私有变量 在私有作用域中,我们代码执行的时候遇到一个变 ...

  7. 关于JavaScript预编译和执行顺序以及函数引用类型的思考

    昨晚在对项目中的一部分做模块化处理的时候,遇到了一个问题,一个重新定义的function对一个通用类中的function进行赋值覆盖的时候,失败了.问题抽象出来是这样的: <script > ...

  8. ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案 try.dot.net 的正确使用姿势 .Net NPOI 根据excel模板导出excel、直接生成excel .Net NPOI 上传excel文件、提交后台获取excel里的数据

    ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案   ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不 ...

  9. 我理解的js中预解释

    浏览器在执行代码前,先找带var和带function的地方,把带var的声明且赋予初始值undefined,把带function的声明且定义. 带var关键字预解释 让我们先看下这段代码执行的结果: ...

随机推荐

  1. nginx配置404

    1.创建一个404错误时显示的页面 2.在nginx.conf中的http区域加入: fastcgi_intercept_errors on; 3.在nginx.conf的server区域(如果网站有 ...

  2. 八、java集合类

    与数组的区别: 数组的长度是固定的,集合的长度是可变的.数组用来存放基本类型的数据,集合用来存放对象的引用. 1.集合类接口的常用方法 COllection接口是层次结构中的根接口,该接口提供了添加和 ...

  3. 判断浏览器是否为IE内核的最简单的方法

    没啥说的,直接贴代码,算是ie hack了. if (!+[1,]) { alert('is ie'); }

  4. FreeSWITCH 1.6在Debian 8上的安装

    鉴于上次在CentOS 7上安装不成功,这次换Debian. 现在已经成功的CentOS 7上安装好了. 感兴趣的同学移步https://freeswitch.org/confluence/displ ...

  5. 《安全智库》:48H急速夺旗大战通关writeup(通关策略)

    作者:ByStudent   题目名字 题目分值 地址 MallBuilder2 350 mall.anquanbao.com.cn MallBuilder1 200 mall.anquanbao.c ...

  6. ABAP 内表 详解

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  7. 虚拟机guest为windows7的环境下安装破解版simplify3d_3.0.2

    情形: 1.主机(host):ubuntu 2.虚拟机里安装的操作系统版本(guest):windows 7专业版 3.simplify3d破解版版本:3.0.2(破解需要的工具均在下文的百度云地址里 ...

  8. JSON的操作

    今天遇到了一个要解析JSON的需求.在http://stackoverflow.com/questions/1826727/how-do-i-parse-json-with-ruby-on-rails ...

  9. JZs3c2440学习笔记一

    1.连线 串口线usb-com,USB下载线 2.驱动安装 USB-serial,  dnw的sec s3c2410x test驱动安装(win7下安装方法搜索:百问网WIN7,64,dnw) 3.烧 ...

  10. oracle 10g正则表达式 REGEXP_LIKE 用法

    ORACLE中的支持正则表达式的函数主要有下面四个:1,REGEXP_LIKE :与LIKE的功能相似2,REGEXP_INSTR :与INSTR的功能相似3,REGEXP_SUBSTR :与SUBS ...