带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. MySQL基础(三)——约束

    MySQL基础(三)--约束 约束是在表上强制执行的数据校验规则,主要用于维护表中数据的完整性以及当数据之间有以来关系时,保护相关的数据不会被删除. 根据约束对列的限制,可以划分为:单列约束(只约束一 ...

  2. oracle一列中的数据有多个手机号码用逗号隔开,我如何分别取出来?

    ID NUMBER1 137xxxx,138xxxx取出来成ID NUMBER1 137xxxx1 138xxxx create table test (id int, phone varchar2( ...

  3. GHOST系统锁定主页常用软件及解决方案

    网络下载的GHOST系统,很多锁定主页,无法用360等更改,卸载里面也不含有锁定主页的软件名称.其中常用的锁定的主页的软件有: 1.百度组件. 一般在C盘含有BAIDU的文件夹内,找到卸载即可. 2. ...

  4. Linux内核中的GPIO系统之(3):pin controller driver代码分析

    一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道,pin control subsystem也不例外,被它驱动的硬件叫做pin controller(一般ARM soc的datash ...

  5. 【leetcode❤python】409. Longest Palindrome

    #-*- coding: UTF-8 -*- from collections import Counterclass Solution(object):    def longestPalindro ...

  6. Setting Margin Properties in code

    http://stackoverflow.com/questions/1003772/setting-margin-properties-in-code The problem is that Mar ...

  7. Beaglebone Black– 智能家居控制系统 LAS - 网页服务器 Node.js 、Web Service、页面 和 TCP 请求转 UDP 发送

    上一篇,纯粹玩 ESP8266,写入了 init.lua 能收发 UDP.这次拿 BBB 开刀,用 BBB host 一个 web server ,用于与用户交互,数据来自 ESP8266 的 UDP ...

  8. servlet&jsp高级:第四部分

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

  9. Python-爬虫初学

    #爬取网站中的图片 1 import re #正则表达式库 import urllib #url链接库 def getHtml(url): page = urllib.urlopen(url) #打开 ...

  10. android——学习:网格布局——GridLayout

    Android一开始就提供了几种布局控件,如线性布局LinearLayout.相对布局RelativeLayout和表格布局TableLayout等,但在很多情况下,这些布局控件是不能满足要求的,因此 ...