浅谈JavaScript代码预解析 + 示例详解

概念

  • var 声明的变量在预解析的时候只执行声明,不会执行定义,默认值是 undefined
  • function 声明的函数在预解析的时候会提早声明而且会同时定义。
  • 变量名重复声明无效
  • 预解析过得代码不会再执行阶段执行

示例一

console.log(a);  // 打印函数a函数体(function a() { console.log('a') })

var a = 10;

console.log(a);  // 10

function a() { console.log('a') }

console.log(a);  // 10
复制代码
预解析过程
  1. 首先预解析到有变量 a 存在,所以记录下 a 这个名字,和其值 undefined
  2. 接着预解析到有函数 a 声明,记录下函数名 a
  3. 可是发现已经记录了一个 a ,所以该操做无效,将函数体与 a 这个名字相关联
  4. 解析完毕
预解析过程代码
  1. a = undefined
  2. a = function () { console.log('a') }
预解析结果
  1. a = function () { console.log('a') }
执行过程
  1. 打印变量 a 的值 function a() { console.log('a') }
  2. 变量 a 赋值为10,将原来关联的函数覆盖
  3. 打印变量 a 的值 10
  4. 打印变量 a 的值 10
  5. 执行完毕
执行过程代码
  1. console.log(a)
  2. a = 10
  3. console.log(a)
  4. console.log(a)

示例二

console.log(fn)  // 函数fn函数体(function fn() { console.log(2) })

function fn() { console.log(1) }

console.log(fn)  // 函数fn函数体(function fn() { console.log(2) })

var fn = 10    

console.log(fn)  // 10

function fn() { console.log(2) }   

console.log(fn)  // 10
复制代码
预解析过程
  1. 首先预解析到有函数 fn 声明,所以记录 fn 这个名字,并关联其函数体
  2. 接着预解析到变量 fn 声明,记录下变量名 fn
  3. 可是发现已经记录了一个 fn ,所以该操做无效
  4. 接着预解析到有函数 fn 声明,所以记录 fn 这个名字
  5. 可是发现已经记录了一个 fn ,所以该操做无效,接着关联其函数体
  6. 解析完毕
预解析过程代码
  1. fn = function () { console.log(1) }
  2. fn = function () { console.log(2) }
预解析结果
  1. fn = function () { console.log(2) }
执行过程
  1. 打印变量 fn 的值 function fn() { console.log(2) }
  2. 打印变量 fn 的值 function fn() { console.log(2) }
  3. 变量 fn 赋值为10,将原来关联的函数覆盖
  4. 打印变量 fn 的值 10
  5. 打印变量 fn 的值 10
  6. 执行完毕
执行过程代码
  1. console.log(fn)
  2. console.log(fn)
  3. fn = 10
  4. console.log(fn)
  5. console.log(fn)