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函数声明和函数表达式的区别相关推荐

  1. Javascript 函数声明和函数表达式的区别

    2019独角兽企业重金招聘Python工程师标准>>> Javascript Function无处不在,而且功能强大!通过Javascript函数可以让JS具有面向对象的一些特征,实 ...

  2. JavaScript的函数声明与函数表达式的区别

    1)函数声明(Function Declaration); // 函数声明function funDeclaration(type){return type==="Declaration&q ...

  3. JavaScript 函数声明,函数表达式,匿名函数,立即执行函数之区别

    函数声明:function fnName () {-};使用function关键字声明一个函数,再指定一个函数名,叫函数声明. 函数表达式 var fnName = function () {-};使 ...

  4. 逆推继承看原型 函数的角色 函数声明和函数表达式的区别 函数中this指向的问题

    逆推继承看原型 <!DOCTYPE html> <html lang="en"> <head><meta charset="UT ...

  5. JS中的函数声明和函数表达式

    JS中的函数声明和函数表达式 1. 函数声明定义一个具有指定参数的函数 函数声明提升, 函数声明在JS解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用 hoist ...

  6. 函数声明与函数表达式的区别

    一. 定义函数的方式 定义函数有两种方式:函数声明和函数表达式. 函数声明的语法是这样的: function functionName(arg0,arg1){//函数体 } 首先是function关键 ...

  7. 函数声明和函数表达式的区别:

    函数声明和函数表达式的区别: function sum(){}; 函数声明,和var一样,会被提前到代码最前面定义.fn1():// 1 function fn1(){​ console.log(1) ...

  8. javascript 函数声明与函数表达式的区别

    还是一样,先上代码: <script>var f = function g() {return 1;};if (false) {f = function g(){return 2;};}a ...

  9. JavaScript程序开发(十四)—函数声明与函数表达式

    函数声明和函数表达式虽然都是在声明一个函数,但是二者有区别,解析器对二者的解析并非是一视同仁的.解析器会率先解析读取函数声明,并使其可以在执行任何代码前可用(可以访问):至于函数表达式,则必须等到解析 ...

最新文章

  1. v深入研究Clang(四) Clang编译器的简单分析
  2. 解决android模拟器不能访问网络的问题
  3. python报错 TypeError: an integer is required
  4. 深入到系统组件是否白盒测试_2019年系统集成项目管理工程师:第一章 信息化知识(三)要点?...
  5. haproxy搭建web群集
  6. HDU 6127 Hard challenge(极角 + 二分)
  7. 正确使用计算机说课稿,《初识计算机》说课稿
  8. win7系统更改密码策略的设置方法
  9. 套接字(Windows)
  10. 分析日志下载时间脚本
  11. python画图代码-Python为啥这么牛?一行Python代码除了画图竟然还有这些功能!
  12. JVM 怎么判断对象已经死了?
  13. 【物联网中间件平台-03】YFIOs安装指南
  14. 使用adblock plus浏览器插件屏蔽广告
  15. 回溯法 子集和问题
  16. python 视频 特效,Python实现高级电影特效
  17. [MATLABSIMULINK] 如何提取并处理Simscape Power System 中powergui的谐波分析数据
  18. 嵌入式开发入门基础篇
  19. linux scp 排除文件夹,scp复制文件时排除指定文件
  20. ORA-12528: TNS: 监听程序: 所有适用例程都无法建立新连接

热门文章

  1. python Day1作业:用户三次登陆锁定
  2. LoadRunner解决超时错误
  3. SLAM中的逆深度参数化
  4. Python中最好用的命令行解析工具:argparse
  5. 【php】函数重载问题
  6. POJ 1733 Parity game(带权并查集)
  7. 两种控制器的跳转与回跳
  8. 电厂MIS,SIS简介
  9. 数据集成之主数据管理(一)基础概念篇
  10. ORACLE学习第三天