函数的标识符也就是通常说的函数名,在函数声明中不可省略,而函数表达式中可以省略。
我们都知道,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 //undefinedfoo=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();
当每个函数都给上标识符,那么调用栈就会显示被调用的函数的名字
是不是看起来就比较明朗√