在Javascript中允许函数通过直接量来定义。一般情况下,我们定义函数时,最常见的方式是通过function语句进行定义,例如:

function sum(a,b){
    return a+b;
}

这样,sum这个函数就在它所在的作用域中可以被任意调用了。除此之外,函数的定义方式可以通过另外一种方式,就是通过直接量定义。例如上面这个例子,我们可以用另外一种方式:

var sum=function(a,b){
    return a+b;
}

上述代码就是函数通过直接量的方式进行定义。函数直接量是一个表达式,它可以定义匿名函数。函数直接量的语法和function语句十分相似,只不过, 它被用作表达式的一部分,而不是用作语句了。在函数直接量定义中,右侧的function所定义的是匿名函数,并将这个匿名函数的引用传递给表达式左侧。

关于函数直接量定义,需要说明几点:

第一,函数直接量定义方式定义出来的函数是一个匿名函数,尽管通过表达式赋值语句将这个函数赋值给了左侧的变量名,但是,左侧的变量被赋值的是这个匿名函数的引用。

第二,由于函数直接量的定义方式中(代码2),实际上function已经作为一个表达式来看待,因此,表达式左侧的变量就必须在该语句执行之后才会引用 右侧的匿名函数,也就是说,在该语句执行之前,作用域中仅仅是知道有个变量是sum,但是类型未知。于此相反的是,常规的函数语句(代码1)会在 Javascript执行之前进行“预处理”,在它的作用域中,sum一开始就被认知为函数。 一个非常简单的例子:

alert(a);//弹出undefined
alert(b);//弹出b.toString()后的结果
var a=function(){return 1;}
function b(){return 1;}
alert(a);//弹出a.toString()后的结果

上 述代码中,第一次alert(a)时,由于“预处理”,该作用域中已经知道存在一个变量a,但是由于还没有执行到第3行,因此,它是undefind,而 b则在一开始时,就已经知道它的类型是函数了。因此,alert(b)时,它会直接执行b.toString()方法尽管它的定义在执行语句的下面。

第三, 虽然函数直接量创建的是匿名函数,但是它的语法也规定它可以指定函数名。只不过这个函数名只在编写调用自身的递归函数时非常有效。为了说明这个问题,先看下面的代码:

var sum=function temp(n){return n==1?1:n*temp(n-1);}
alert(sum(5));//120
alert(temp(5));//出错

上 面的代码sum是一个计算n的阶乘(n!)运算,我们可以看到,sum的定义是采用函数直接量方式定义的。但是这里存在一个问题,就是它存在一个函数 名:temp。确切的讲,temp不是函数名,因为为前面已经说了,表达式右侧的function是一个匿名函数,因此,temp不可能是函数名(要不怎 么叫匿名函数呢?)。但是,为什么这样的定义语法没有错误呢?因为Javascript允许指定它的函数名,但是这个函数名不是真正的函数名,它是用来为 它自身递归调用时使用的。(函数体中实际上就是一个递归函数)。我大致把temp理解为匿名函数内部作用域中的函数名,它可以这样调用它自己。因此,在执 行到alert(temp(5))时,浏览器报错了,告诉我们temp是未定义的。

但 是需要指出的是,在Javascript的早期版本中,没有正确的实现这种命名了的函数直接量。在IE678这些版本中,Javascript的版本低于 1.5,因此,它对这种方式的处理没有正确的实现。因此,在执行到alert(temp(5))时,它也是显示和执行sum(5)一样的结果。因 此,temp和sum一样,都被赋值了。这个问题在IE9和更高的版本中,得到了统一修正

Javascript的函数直接量定义相关推荐

  1. Javascript: IE中命名函数直接量的Bug?

    [声明:下文为笔记,非原创] 众所周知,JavaScript中可以用函数直接量定义一个函数变量,比如: var myFunc = function (x) {  return "hello, ...

  2. 字面量、对象字面量、函数字面量、函数定义

    #1.字面量(literal) 用于表达一个固定值的表示法,又叫常量. [JS程序执行到代码中的字面量,会立即知道它是什么类型的数据,值是多少] #2.对象字面量 语法: {k1:v1, k2:v2, ...

  3. JavaScript中函数的三种定义方法

    JavaScript中函数定义的三种方法. 函数的三种定义方法分别是:函数定义语句.函数直接量表达式和Function()构造函数的方法.下面依次介绍这几种方法具体怎么实现. 1. 函数定义语句 // ...

  4. javascript的函数定义的区别

    javascript中函数定义通常有两种方法: 1. 普通的函数定义: function f1 (){} 2. 变量式函数定义: var f2 = function(){} 还有一种定义方法是new ...

  5. kettle中使用javascript步骤和fireToDB函数实现自己定义数据库查询

    kettle中使用javascript步骤和fireToDB函数实现自己定义数据库查询 如果你须要实现非传统的数据库查询操作.为了讨论这样的情景,我们如果你须要读取数据库中的正則表達式,然后检查输入的 ...

  6. html 超链接 javascript 函数 java 未定义_JavaScript 学习笔记(一)

    本系列适合作为JS的复习文档. 学习JavaScript,不要以为会做一两个如图片切换.tabs选项卡这样特效,就是精通JavaScript了.JavaScript不仅仅是用来做一两个特效,它更大的用 ...

  7. JS对象直接量,数组直接量和函数直接量

    对象直接量创建一个对象: var obj = {x:[1,2],y:23}; 代码跟下面是一样的. var obj=new Object(); obj.x=new Array(1,2); obj.y= ...

  8. [译] ES6+ 中的 JavaScript 工厂函数(第八部分)

    本文讲的是[译] ES6+ 中的 JavaScript 工厂函数(第八部分), 原文地址:JavaScript Factory Functions with ES6+ 原文作者:Eric Elliot ...

  9. Javascript变量函数浅谈

    一.变量 在javascript变量中可以存放两种类型的值:原始值和引用值. 原始值存储在栈上的简单字段,也就是值直接存储在变量所标示的位置内. 引用值存储在堆内的对象,栈内变量保存的是指向堆内对象的 ...

  10. javascript中函数的全解简介

    来源:itelite <script  language="javascript"> //切记特殊的两种函数声明方式 /* //Function 构造 var f=ne ...

最新文章

  1. 2021年大数据ELK(二十三):Kibana简介
  2. html5伪类效果延缓,CSS3实现伪类hover离开时平滑过渡效果示例
  3. Educational Codeforces Round 64 Div.2 D - 0-1-Tree
  4. 手机游戏开发纹理图片优化心得
  5. Android播放音频的两种方式
  6. audio 相关概念梳理记录
  7. 3C和CE认证的区别
  8. [技巧]WIN10笔记本生成电池损耗报表,与笔记本电池损耗恢复方法
  9. canvas火焰效果
  10. MJUPC-022_编程挑战系列赛第二十二场(以梦为“码“ “数“说未来)题解(C/C++代码)
  11. java模拟器怎么打开apk文件,APK是什么 APK文件怎么打开【详解】
  12. 后台管理系统的美化以及模板的编写
  13. 输入一个大于3的整数n,判定它是否为素数。例题5.9
  14. 大数据入门-什么是Kudu
  15. 防火墙系列(二)-----防火墙的主要技术之包过滤技术,状态检测技术
  16. sci计算机与教育,我院硕士研究生谢若鹏在SCI一区期刊发表高水平学术论文
  17. 百度产品战略的变化历程
  18. 猿创征文 | Shell编程【上篇】
  19. 笔记本机械硬盘无法识别出来
  20. 17.深入浅出:非正弦波发生电路——参考《模拟电子技术基础》清华大学华成英主讲

热门文章

  1. 我 45 岁还写代码,怎么了?
  2. FFmpeg总结(十三)用ffmpeg基于nginx实现直播功能,不用第三方SDK,自研推流拉流
  3. 初二生态系统思维导图_鑫讲堂:初二年级十一月微讲座汇报(二)
  4. 计算机信息管理自荐信个人简历,计算机信息专业英文自荐信
  5. linux线程组和进程区别,Linux中进程和线程之间的区别
  6. 排除包_冷水机压缩机压缩机常见故障和排除方法
  7. java游戏开发总结_java--游戏后端--项目开发总结6--资源下载
  8. ATMV1函数版v1
  9. go语言项目目录文件的管理样式
  10. 实现粗糙表面_爬墙吸盘黑科技成真,还能搞定粗糙表面:浙大提出旋转水涡吸附系统...