关于函数表达式的标识符/函数名

函数的标识符也就是通常说的函数名,在函数声明中不可省略,而函数表达式中可以省略。

我们都知道,javascript引擎将函数名视同变量名,所以采用function命令声明函数时,整个函数会像变量提升一样被提升到代码头部。所以函数声明先执行也不会报错,而函数表达式则会。

对于下面的代码

  foo();
  bar();
  var foo=function bar(){
             console.log(1);
         }

我们根据变量提升和函数提升的理论可以肯定是会报错的,实际运行下

foo(); //Uncaught TypeError: foo is not a function

bar(); //Uncaught ReferenceError: bar is not defined

一开始我的理解是,变量foo被提升后,等同于

var foo //undefined
foo=function bar(){
    console.log(1);
}

浏览器还不知道bar是什么,报错 ReferenceError: defined 很正常。那么下面这样呢:

var foo=function bar(){
    console.log(1);
}
bar();

或者

new function bar(){//作为New表达式(NewExpression)的一部分,它也是函数表达式
    console.log(1);
}
bar();

运行结果依旧是bar(); //Uncaught ReferenceError: bar is not defined。这和想象中不符啊,没有先执行,为什么bar依旧是defined?既然函数标识符被视同变量名,那么对于函数表达式的标识符,怎么会找不到,所以它的作用域在哪里?

所以有了下面的代码:

var foo = function bar(){
    console.log(bar);
}
foo();

打印结果如下:

ƒ bar(){
console.log(bar);
}

果然思路没错,函数表达式的标识符的作用域就在它自己的函数体。函数名是不能调用函数表达式的,如果要调用,也只有递归的情况了。

除此之外,通过搜索引擎找到关于函数表达式的标识符这样的卵用,例子如下:

var f1 = function b1(){
    return f2();
}
var f2 = function b2(){
    return f3();
}
var f3 = function b3(){
    debugger;
}
f1();

当每个函数都给上标识符,那么调用栈就会显示被调用的函数的名字

是不是看起来就比较明朗√

发布了1 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/u011927449/article/details/104055329