浅谈javascript 函数表达式和函数声明的区别


Posted in Javascript onJanuary 05, 2016

javascript中声明函数的方法有两种:函数声明式和函数表达式.

区别如下:

1).以函数声明的方法定义的函数,函数名是必须的,而函数表达式的函数名是可选的.

2).以函数声明的方法定义的函数,函数可以在函数声明之前调用,而函数表达式的函数只能在声明之后调用.

3).以函数声明的方法定义的函数并不是真正的声明,它们仅仅可以出现在全局中,或者嵌套在其他的函数中,但是它们不能出现在循环,条件或者try/catch/finally中,而

    函数表达式可以在任何地方声明.

下面分别用两种方法定义函数:

//函数声明式
 function greeting(){
    console.log("hello world"); 
 }
 
 
 //函数表达式
 var greeting = function(){
   console.log("hello world"); 
 }

下面一个有趣的javascript:

function f() { console.log('I am outside!'); }
(function () {
 if(false) {
  // 重复声明一次函数f
  function f() { console.log('I am inside!'); }
 }
 f();
}());

会输出什么呢?第一反应应该是"I am outside"吧.  结果在chrome中输出"I am inside",IE11直接报错,firefox低一点的版本输出"I am outside"...

chrome输出的结果很明确的反应了用函数声明式声明的函数的特点--函数在声明之前就可以调用.

IE报错显示缺少对象,因为函数声明在了条件里,违背了函数声明式的原则.

函数表达式的作用域:

如果函数表达式声明的函数有函数名,那么这个函数名就相当于这个函数的一个局部变量,只能在函数内部调用,举个栗子:

var f = function fact(x) { 
        if (x <= 1) 
          return 1;
        else 
          return x*fact(x-1);
        };
        alert(fact());  // Uncaught ReferenceError: fact is not defined

fact()在函数内部可以调用,在函数外部调用就会报错:fact未定义.
fact

我们再来详细看下

函数声明

函数声明示例代码

代码如下:

function fn () {
  console.log('fn 函数执行..');
  // code..
}

这样我们就声明了一个名称为fn的函数,这里出个思考,你认为在这个函数的上面来调用他的话会执行吗?还是会报错?

代码如下:fn(); // 在之前调用我们声明的fn函数 function fn () { console.log('fn 函数执行..'); // code..}

控制台输出结果:

浅谈javascript 函数表达式和函数声明的区别

是的,此时fn函数是可以被调用到的,这里来总结下原因。

总结:

1:此时fn函数是变量的结果,默认存储在全局上下文的变量中(可用 window.函数名 来验证)

2:此方式为函数声明,在进入全局上下文阶段创建,代码执行阶段,它们已经可用。ps:javaScript在每次进入方法时都会先初始化上下文环境(由全局 → 局部)

3:它可以影响变量对象(仅影响存储在上下文中的变量)

函数表达式

函数表达式示例代码

代码如下:

var fn = function () {
  console.log('fn 函数【表达式】声明执行..')
  // code..
}

这样我们就声明了一个匿名函数,并且把它的引用指向了变量fn

再次在该表达式声明的函数上下方各调用一次,来看控制台的输出结果。

代码如下:

// 为了清晰的看到控制台的输出,我们在各自调用前后做个标记,增加可读性。
console.log('之前调用开始..');
fn();
console.log('之前调用结束..');
var fn = function () {
  console.log('fn 函数【表达式】声明执行..')
  // code..
}
console.log('之后调用开始..');
fn();
console.log('之后调用开始..');

控制台打印结果:

浅谈javascript 函数表达式和函数声明的区别

可以看到代码在执行到第一次调用fn()函数的时候,提示:fn is not a function (fn 不是一个方法),遇到错误而终止运行。

这说明在第一次调用fn()的同时,var fn 变量没有做为全局对象的一个属性而存在,且 fn 引用的匿名函数上下文也没有被初始化,所以在他之前调用失败。

代码如下:

// 现在先把之前的调用逻辑给注释掉,再看下控制台的输出
//  console.log('之前调用开始..');
//  fn();
//  console.log('之前调用结束..');
  var fn = function () {
    console.log('fn 函数【表达式】声明执行..')
    // code..
  }
  console.log('之后调用开始..');
  fn(); // 在表达式之后调用
  console.log('之后调用开始..');

控制台打印结果:

浅谈javascript 函数表达式和函数声明的区别

可以看出,在该表达式函数之后来调用是可以的,来总结下那是为什么呢?

总结:

1:首先变量本身不做为一个函数存在,而是一个匿名函数的引用(值类型的不属于引用)

2:在代码执行阶段,初始化全局上下文时,它没有被做为全局的一个属性而存在,所以不会造成变量对象的污染

3:该类型的声明一般在插件的开发比较常见,也可做为闭包中回调函数的调用

所以 function fn () {} 并不等于 var fn = function () {} ,他们有本质上的区别。

以上就是本文的全部内容了,思路很清晰,对比也很明确,是篇非常不错的文章,小伙伴们一定要仔细研读下

Javascript 相关文章推荐
基于jquery的滚动鼠标放大缩小图片效果
Oct 27 Javascript
拖动table标题实现改变td的大小(css+js代码)
Apr 16 Javascript
showModalDialog在谷歌浏览器下会返回Null的解决方法
Nov 27 Javascript
Bootstrap框架结合jQuery仿百度换肤功能实例解析
Sep 17 Javascript
原生JS取代一些JQuery方法的简单实现
Sep 20 Javascript
Angularjs实现带查找筛选功能的select下拉框示例代码
Oct 04 Javascript
JS实现AES加密并与PHP互通的方法分析
Apr 19 Javascript
JavaScript实现一个空中避难的小游戏
Jun 06 Javascript
vue.js 实现输入框动态添加功能
Jun 25 Javascript
js根据json数据中的某一个属性来给数据分组的方法
Oct 08 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【凹多边形的分离轴检测算法】
Dec 13 Javascript
基于JavaScript判断两个对象内容是否相等
Jan 10 Javascript
JavaScript实现下拉菜单的显示和隐藏
Jan 05 #Javascript
jQuery实现二级下拉菜单效果
Jan 05 #Javascript
基于JavaScript实现简单的随机抽奖小程序
Jan 05 #Javascript
jquery中ajax处理跨域的三大方式
Jan 05 #Javascript
基于JavaScript代码实现随机漂浮图片广告
Jan 05 #Javascript
多个js毫秒倒计时同时进行效果
Jan 05 #Javascript
在WordPress中加入Google搜索功能的简单步骤讲解
Jan 04 #Javascript
You might like
php牛逼的面试题分享
2013/01/18 PHP
PHP中的闭包(匿名函数)浅析
2015/02/07 PHP
smarty高级特性之对象的使用方法
2015/12/25 PHP
YII CLinkPager分页类扩展增加显示共多少页
2016/01/29 PHP
PHP中Restful api 错误提示返回值实现思路
2016/04/12 PHP
laravel实现图片上传预览,及编辑时可更换图片,并实时变化的例子
2019/11/14 PHP
PHP实现微信提现功能(微信商城)
2019/11/21 PHP
JavaScript中this关键字使用方法详解
2007/03/08 Javascript
Jquery 获取checkbox的checked问题
2011/11/16 Javascript
js性能优化 如何更快速加载你的JavaScript页面
2012/03/17 Javascript
关于jquery input textare 事件绑定及用法学习
2013/04/03 Javascript
vue.js+boostrap项目实践(案例详解)
2016/09/21 Javascript
AngularJS改变元素显示状态
2017/04/20 Javascript
微信小程序实现image组件图片自适应宽度比例显示的方法
2018/01/16 Javascript
vue中监听返回键问题
2019/08/28 Javascript
Python创建xml的方法
2015/03/10 Python
python使用正则表达式分析网页中的图片并进行替换的方法
2015/03/26 Python
Python中read()、readline()和readlines()三者间的区别和用法
2017/07/30 Python
python list元素为tuple时的排序方法
2018/04/18 Python
Python 实现输入任意多个数,并计算其平均值的例子
2019/07/16 Python
解决python 读取excel时 日期变成数字并加.0的问题
2019/10/08 Python
python GUI库图形界面开发之PyQt5窗口布局控件QStackedWidget详细使用方法
2020/02/27 Python
Python函数参数分类原理详解
2020/05/28 Python
利用Python的folium包绘制城市道路图的实现示例
2020/08/24 Python
Alpine安装Python3依赖出现的问题及解决方法
2020/12/25 Python
用css3写出气球样式的示例代码
2017/09/11 HTML / CSS
HTML5 Canvas鼠标与键盘事件demo示例
2013/07/04 HTML / CSS
电气工程及自动化专业自荐书范文
2013/12/18 职场文书
初中政治教学反思
2014/01/17 职场文书
安全生产汇报材料
2014/02/17 职场文书
学生期末评语大全
2014/04/30 职场文书
教师竞聘演讲稿
2014/05/16 职场文书
初中毕业生感言
2015/07/31 职场文书
2016年全国爱眼日宣传教育活动总结
2016/04/05 职场文书
SpringCloud的JPA连接PostgreSql的教程
2021/06/26 Java/Android
CSS布局之浮动(float)和定位(position)属性的区别
2021/09/25 HTML / CSS