扒一扒JavaScript 预解释

  带var关键字预解释

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

  

复制代码 代码如下:

  alert(n);//弹出undefined

  var n = 10;

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

  

复制代码 代码如下:

  alert(n);

  n = 10;

  运行报如下错误:

扒一扒JavaScript 预解释

  为何这次会报错,原因是代码在运行的时候,没有声明这个变量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关键字在预解释时声明和定义同时被预解释。这时我们再回头分析下第一段代码,分析如下:

扒一扒JavaScript 预解释

  无节操(坑爹)的预解释

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

  

复制代码 代码如下:

  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);

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

扒一扒JavaScript 预解释

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

  

复制代码 代码如下:

  fn();

  function fn() {

  alert('1');

  }

  fn();

  function fn() {

  alert('2');

  }

  fn();

  代码分析图如下:

扒一扒JavaScript 预解释

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

  总结:

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