函数声明提升优先级高于变量声明提升; 提升就是声明(变量/函数)提至当前作用域的最顶部,赋值语句留在原地

发布时间 2023-11-16 12:40:17作者: 龙陌

执行以下程序,输出结果为()

var a = 2;
function fn(){
  b();
  return ;
  var a = 1;
  function b(){
    console.log(a);
  }
}
fn();

A
1

B
2

C
undefined

D
抛出异常

正确答案:C

虽然return 语句可以终止函数,但是return语句后如果有变量和函数声明,仍然存在变量提升和函数提升,
即在函数fn内,函数b和局部变量a会提升到函数的开头部分。
当调用函数b时,需要查找并输出a的值,根据作用域链查找规则,会先在函数fn内找到已经声明的局部变量a,由于局部变量a的赋值并未跟着发生提升,因此输出的a值为undefined,C选项正确。

这是考察JS中提升(hoist)的问题,也就是变量提升和函数提升

要注意几个点
1.函数声明提升优先级高于变量声明提升
2.提升就是声明(变量/函数)提至当前作用域的最顶部,赋值语句留在原地,
3.函数创建有3个形式,函数声明和函数表达式 以及 new Function构造函数。
4.只有函数声明才有函数提升。...其实2个都有提升,表达式提升的是变量了。

//原来的代码
var a = 2;
function fn(){
        b();
        return ;
        var a = 1;
        function b(){
            console.log(a);
        }
}
fn();

//实际上的代码
var a = 2;
function fn(){
    function b(){
      console.log(a);
    }
    var a //变量声明提升,默认赋值为undefined
    b(); //执行函数b,在当前作用域找到a,值为undefined
    return;//return后面的语句不再执行,a没有被赋值为1
    a = 1; //在原来的位置才会赋值,但不会执行到这里
}
fn();

函数声明和函数表达式的区别(以及提升的不同)

就是function左边没有东西就是函数声明,有就是表达式

//函数声明
  function f1(){
    console.log('我是函数声明')
  }
  //函数表达式
  var f2 = function () {
    console.log('我是函数表达式')
  }

函数发生提升后

// 函数声明--提升
function f1() { 
  console.log('我是函数声明')
}
var f2;
f1() //'我是函数声明'
f2() //error:f2 is not a function
// 函数表达式
f2 = function() {
  console.log('我是函数表达式')
}

JS中所有声明(val / let / const /function() /class / function*) 都存在提升,不过像let const class这些因为TDZ的原因‘表现’得像没有提升。