Skip to content

07 变量提升的处理机制和匿名函数具名化

变量提升(预解析)

在“当前上下文”代码自上而下执行之前,浏览器会把所有带`var/function`关键字的进行提前的声明或者定义
    + 带var的指示提前声明
    + 带function的是提前声明加赋值(定义)
js
//=>匿名函数具名化「更规范一些」
var fn = function sum() {
  console.log('OK')
  // sum = 100;
  // console.log(sum); //->具名化的名字可以在函数内部的上下文中使用「代表函数本身」;默认情况下,其值是不能被修改的;

  // console.log(sum); //->undefined 虽然具名化的名字会在当前函数的私有上下文中被声明,当做私有变量处理,但是他的优先级是比较低的,一但出现同名的其他声明方式,则以其他方式为主
  // var sum;
}
fn()

// sum(); //->Uncaught ReferenceError: sum is not defined 匿名函数具名化,设置的函数名不能在函数以外使用「因为并没有在当前上下文中声明这个变量」
js
/*
 * EC(G)
 *   变量提升:
 *     fn=0x000 [[scope]]:EC(G)
 *    「老版本浏览器中」
 *       sum=0x001 [[scope]]:EC(G)
 *    「新版本浏览器」
 *       sum;
 */
console.log(sum, fn) //->undefined   ƒ fn() {}
function fn() {}
if (1 !== 1) {
  function sum() {}
}
js
/*
 * EC(G)
 *  变量提升:
 *    var a;
 *    fn1=0x000; [[scope]]:EC(G)
 *    var fn2;
 */
console.log(a) //->undefined
fn1()
var a = 10 //全局a=10
function fn1() {
  //直接跳过「变量提升阶段已经创建了」
  /*
   * EC(FN1)
   *   作用域链:<EC(FN1),EC(G)>
   *   形参赋值:--
   *   变量提升:
   *     var a;
   */
  console.log('fn1') //->'fn1'
  console.log(a) //->undefined
  var a = 20 //私有a=20
  console.log(a) //->20
}
fn2() //->Uncaught TypeError: fn2 is not a function
var fn2 = function () {
  //函数表达式
  console.log('fn2')
}
fn2()
js
'use strict' //->让JS使用严格模式
// 自执行函数
;(function anonymous(x) {
  if (x < 0) return
  console.log(x)
  // 递归调用
  // arguments.callee 函数本身
  // 开启严格模式则会报错 Uncaught TypeError: arguments.calle is not a function
  // arguments.calle(x - 1);

  anonymous(x - 1)
})(10)