}

传智播客旗下技术交流社区北京校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

函数声明和函数表达式到底有什么区别?

要弄清函数声明和函数表达式的区别,首先要明白在JS中声明和表达式的行为存在十分微妙而又十分重要的差别。

首先,函数声明会在任何表达式被解析和求值之前先行被解析和求值。即使声明位于源代码中的最后一行,它也会先于同一作用域中位于最前面的表达式被求值。其实原理就是靠的作用域与变量提升机制,这块先不细说,后面单独写篇文章吧。

console.log(fn());
function fn(){
    return 'helloNitx';
}
//打印:helloNitx

console.log(fn());
var fn = function(){
    return 'helloNitx';
}
//输出:TypeError: fn is not a function
1
2
3
4
5
6
7
8
9
10
11
这里要补充个重要的知识点:由于通过条件语句控制函数声明的行为并未标准化,因此在不同环境下可能会得到不同的结果。所以不要在条件语句中使用函数声明,而可以使用函数表达式。

//错误示例:不要把函数声明放在条件语句中,有的浏览器会把fn声明为返回1的函数,有的浏览器把fn声明为返回2的函数
if(true){
    function fn(){
        console.log('1');
    }
}else {
    function fn(){
        console.log('2');
    }
}
fn();   

//伪正确示例:
var foo = null;
if(true){
    foo = function(){
        console.log('3');
    }
}else {
    foo = function(){
        console.log('4');
    }
}
foo();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
注意,这里第二个示例为什么我注释为伪正确示例?看下面这段关于函数声明规则官方摘录:

函数声明只能出现在程度或函数体内。从句法上讲,它们不能出现在块中,比如不能出现在if、while或for语句。因为块只能包含语句,而不能包含函数声明这样的源元素。而唯一可能让表达式出现在块中的情形,就是让它作为表达式语句的一部分。但是规范也明确规定表达式语句不能以function开头。而这实际上就是说,函数表达式同样也不能出现在语句或块中。由于存在上述限制,只要函数出现在块中,实际上就可以看作是一个语法错误,而不用管什么函数声明或表达式。
所以较佳实践应是,不要把函数写在语句或块中,不管是声明函数还是表达式函数。

表达式函数里有匿名表达式函数和命名表达式函数。

所谓的命名函数表达式,指的是有名字的函数表达式,这个名字技术上称为标识符。var bar = function foo(){};实际上就是一个命名函数表达式,这里有个细节需要注意:即这个名字(标识符)只在新定义的函数的作用域中有效,规范要求标识符不能在外围的作用域中有效。

var f = function foo(){
    return typeof foo;      //foo只在内部作用域中有效
}
console.log(typeof foo);    //undefined
console.log(typeof f);      //function
1
2
3
4
5
这个名字(标识符)的作用在于调试方便,其他与匿名函数表达式如var bar = function(){};没有区别。另外浏览器的调试器通常功能较简,遇到复杂的程序时,效果不大。

在实际开发中,函数声明和函数表达式可以灵活选择,只是需要理清两点:变量和作用域的提升问题,在函数表达式中注意匿名函数表达式和命名函数表达式的区别。
---------------------
【转载,仅作分享,侵删】
作者: 一期一会
原文:https://blog.csdn.net/qq_34832846/article/details/86221223


分享至 : QQ空间
收藏

1 个回复

倒序浏览
奈斯
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马
关闭

站长推荐 上一条 /5 下一条