js函数声明和函数表达式的区别
Javascript Function无处不在,而且功能强大!通过Javascript函数可以让JS具有面向对象的一些特征,实现封装、继承等,也可以让代码得到复用。但事物都有两面性,Javascript函数有的时候也比较“任性”,你如果不了解它的“性情”,它很可能给你制造出一些意想不到的麻烦(bugs)出来。
Javascript Function有两种类型:
1)函数声明(Function Declaration);
// 函数声明function funDeclaration(type){return type==="Declaration";}
2)函数表达式(Function Expression)。
// 函数表达式var funExpression = function(type){return type==="Expression";}
上面的代码看起来很类似,感觉也没什么太大差别。但实际上,Javascript函数上的一个“陷阱”就体现在Javascript两种类型的函数定义上。下面看两段代码(分别标记为代码1段和代码2段):
1 funDeclaration("Declaration");//=> true 2 function funDeclaration(type){ 3 return type==="Declaration"; 4 }
1 funExpression("Expression");//=>error 2 var funExpression = function(type){ 3 return type==="Expression"; 4 }
用函数声明创建的函数funDeclaration可以在funDeclaration定义之前就进行调用;而用函数表达式创建的funExpression函数不能在funExpression被赋值之前进行调用。为什么会这样呢?!这就要理解Javascript Function两种类型的区别:用函数声明创建的函数可以在函数解析后调用(解析时进行等逻辑处理);而用函数表达式创建的函数是在运行时进行赋值,且要等到表达式赋值完成后才能调用。这个区别看似微小,但在某些情况下确实是一个难以发现的陷阱。出现这个陷阱的本质原因体现在这两种类型在Javascript function hoisting(函数提升)和运行时机(解析时/运行时)上的差异。关于变量提升,https://www.cnblogs.com/gaoht/p/10404911.html上面两段代码的函数提升可示意为下图:
代码1段JS函数等同于:
function funDeclaration(type){return type==="Declaration";}funDeclaration("Declaration");//=> true
代码2段JS函数等同于:
var funExpression;funExpression("Expression");//==>errorfunExpression = function(type){return type==="Expression";}
上述代码在运行时,只定义了funExpression变量,但值为undefined。因此不能在undefined上进行函数调用。此时funExpression赋值语句还没执行到。为了进一步加深JS函数两种类型的区别,下面给出一个更具迷惑性的示例,请看下面的代码(代码段4):
var sayHello;
console.log(typeof(sayHey)); //=>function
console.log(typeof(sayHo)); //=>undefinedfunction sayHey() {console.log("sayHey");}sayHello = function sayHo() {console.log("sayHello");}function sayHey() {console.log("sayHey2");}sayHello = function sayHo() {console.log("sayHello2");}sayHey(); // => sayHey2
sayHello(); // => sayHello
分析:sayHey是用函数声明创建的,在JS解析时JS编译器将函数定义进行了函数提升,也就是说,在解析JS代码的时候,JS编译器(条件判断不形成新的作用域,两个sayHey函数定义都被提升到条件判断之外)检测到作用域内有两个同名的sayHey定义,第一个定义先被提升,第二个定义接着被提升(第二个定义在第一个定义之下),第二个定义覆盖了第一个sayHey定义,所以sayHey()输出sayHey2;而sayHello是用函数表达式创建的,其表达式的内容是在JS运行时(不是解析时)才能确定(这里条件判断就起到作用了),所以sayHello表达式执行了第一个函数定义并赋值,则sayHello()输出sayHello。
代码段4的代码实际上等同于下面的代码(代码段5):
var sayHello;function sayHey() {console.log("sayHey");
}function sayHey() {console.log("sayHey2");
}
console.log(typeof(sayHey)); //=>function
console.log(typeof(sayHo)); //=>undefined//hoisting...
sayHello = function sayHo() {console.log("sayHello");
}//hoisting...
sayHello = function sayHo() {console.log("sayHello2");
}sayHey(); // => sayHey2
sayHello(); // => sayHello
总结
Javascript 中函数声明和函数表达式是存在区别的,函数声明在JS解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用。而函数表达式的值是在JS运行时确定,并且在表达式赋值完成后,该函数才能调用。这个微小的区别,可能会导致JS代码出现意想不到的bug,让你陷入莫名的陷阱中。
最后附
上图为sayHello函数执行的主要步骤示意图。
上图为sayHey函数执行主要步骤的示意图。若对闭包感兴趣,可以看另外一篇博文https://www.cnblogs.com/gaoht/p/10430853.html
转载于:https://www.cnblogs.com/gaoht/p/10401863.html
js函数声明和函数表达式的区别相关推荐
- Javascript 函数声明和函数表达式的区别
2019独角兽企业重金招聘Python工程师标准>>> Javascript Function无处不在,而且功能强大!通过Javascript函数可以让JS具有面向对象的一些特征,实 ...
- JavaScript的函数声明与函数表达式的区别
1)函数声明(Function Declaration); // 函数声明function funDeclaration(type){return type==="Declaration&q ...
- JavaScript 函数声明,函数表达式,匿名函数,立即执行函数之区别
函数声明:function fnName () {-};使用function关键字声明一个函数,再指定一个函数名,叫函数声明. 函数表达式 var fnName = function () {-};使 ...
- 逆推继承看原型 函数的角色 函数声明和函数表达式的区别 函数中this指向的问题
逆推继承看原型 <!DOCTYPE html> <html lang="en"> <head><meta charset="UT ...
- JS中的函数声明和函数表达式
JS中的函数声明和函数表达式 1. 函数声明定义一个具有指定参数的函数 函数声明提升, 函数声明在JS解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用 hoist ...
- 函数声明与函数表达式的区别
一. 定义函数的方式 定义函数有两种方式:函数声明和函数表达式. 函数声明的语法是这样的: function functionName(arg0,arg1){//函数体 } 首先是function关键 ...
- 函数声明和函数表达式的区别:
函数声明和函数表达式的区别: function sum(){}; 函数声明,和var一样,会被提前到代码最前面定义.fn1():// 1 function fn1(){ console.log(1) ...
- javascript 函数声明与函数表达式的区别
还是一样,先上代码: <script>var f = function g() {return 1;};if (false) {f = function g(){return 2;};}a ...
- JavaScript程序开发(十四)—函数声明与函数表达式
函数声明和函数表达式虽然都是在声明一个函数,但是二者有区别,解析器对二者的解析并非是一视同仁的.解析器会率先解析读取函数声明,并使其可以在执行任何代码前可用(可以访问):至于函数表达式,则必须等到解析 ...
最新文章
- v深入研究Clang(四) Clang编译器的简单分析
- 解决android模拟器不能访问网络的问题
- python报错 TypeError: an integer is required
- 深入到系统组件是否白盒测试_2019年系统集成项目管理工程师:第一章 信息化知识(三)要点?...
- haproxy搭建web群集
- HDU 6127 Hard challenge(极角 + 二分)
- 正确使用计算机说课稿,《初识计算机》说课稿
- win7系统更改密码策略的设置方法
- 套接字(Windows)
- 分析日志下载时间脚本
- python画图代码-Python为啥这么牛?一行Python代码除了画图竟然还有这些功能!
- JVM 怎么判断对象已经死了?
- 【物联网中间件平台-03】YFIOs安装指南
- 使用adblock plus浏览器插件屏蔽广告
- 回溯法 子集和问题
- python 视频 特效,Python实现高级电影特效
- [MATLABSIMULINK] 如何提取并处理Simscape Power System 中powergui的谐波分析数据
- 嵌入式开发入门基础篇
- linux scp 排除文件夹,scp复制文件时排除指定文件
- ORA-12528: TNS: 监听程序: 所有适用例程都无法建立新连接