Javascript的函数直接量定义
在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的函数直接量定义的更多相关文章
- Javascript中函数及变量定义的提升
<html> <head> <title>函数提升</title> <script language="javascript" ...
- Function()构造函数与函数直接量
Function()构造函数与函数直接量 制作人:全心全意 在JavaScript中,除了可使用基本的function语句定义函数之外,还可以使用另外两种方式来定义,即使用Function()构造函数 ...
- js拾遗: 函数字面量
今天落叶同学发我一篇文章,我看到一个"新"名词 "函数字面量" (也可叫直接量),当时我就郁闷了,这是什么东西? 我怎么没听说过..回头翻了下权威指南,在第 4 ...
- (转载)JavaScript中匿名函数,函数直接量和闭包
首先,我们先看看下面几种写法:1.function f(x){return x*x;};f(x);2.(function(x){return x*x;})(x);3.(function(x){retu ...
- JavaScript函数的多种定义方法
缘起 javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法也是对 javascript语言特性更进一步的深入理解, ...
- kettle中使用javascript步骤和fireToDB函数实现自己定义数据库查询
kettle中使用javascript步骤和fireToDB函数实现自己定义数据库查询 如果你须要实现非传统的数据库查询操作.为了讨论这样的情景,我们如果你须要读取数据库中的正則表達式,然后检查输入的 ...
- JavaScript中函数的定义
JavaScript中函数的定义 制作人:全心全意 在JavaScript中,函数是由关键字function.函数名加一组参数以及置于大括号中需要执行的一段代码定义的.定义函数的基本语法格式如下: f ...
- JavaScript中函数的定义!
JavaScript中函数的定义! 1 自定义函数(命名函数) function fun() {}; 2 函数表达式(匿名函数) var fun = function () {}; 3 利用 new ...
- 如何定义 Java 的回调函数,与 JavaScript 回调函数的区别
JavaScript 中的回调函数 在 JavaScript 中经常使用回调函数,比如:get 请求.post 请求等异步任务.在我们请求之前以及请求之后,都需要完成一些固定的操作,比如:请求之前先从 ...
随机推荐
- ORACLE中RECORD、VARRAY、TABLE、IS REF CURSOR 的使用及实例详解
ORACLE中RECORD.VARRAY.TAB.IS REF CURSOR LE的使用及实例详解 create or replaceprocedure PRO_RECORD_ROW_TAB_EXAM ...
- Java基础操作面试题:Map集合排序 需要TreeMap 构造方法参数有比较器 输入字符串,统计A、B、C、D、出现次数,由高到低输出字母和出现次数,使用Map集合完成此题
Map和Collections是同级别的,不能像List排序那样直接用Collections.sort(new Comparator<?>(){ 复写compara方法}); HashMa ...
- cocos2dx 使用XMLHttpRequest时回调status为0的问题
今天使用cocos连接http访问时,使用XMLHttpRequest在pc上反问时正常的返回了status=0,但是在android上去返回status是0,看了一下底层代码, 发现status只有 ...
- IOS7的变化
API变化: 1.弃用 MKOverlayView 及其子类,使用类 MKOverlayRenderer: 2.弃用 Audio Toolbox framework 中的 AudioSession A ...
- *运算和&运算
/* &:取地址运算符 *:指针运算符(或称为间接运算符),取指针所指向的对象的内容 */ int a,b; int *pointer_1, *pointer_2; pointer_1 = & ...
- attachEvent和addEventListener 的使用方法和区别
attachEvent方法,为某一事件附加其它的处理事件.(不支持Mozilla系列)addEventListener方法 用于 Mozilla系列document.getElementById(&q ...
- day3- python 注册
# .先把文件内容的账号密码放到list/字典 f = open('users') result = f.read() f.close() user_list = result.split() # u ...
- 如何用 CSS 和 D3 创作一个无尽的六边形空间
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/NBvrWL 可交互视频 此视频是可 ...
- python爬虫基础16-cookie在爬虫中的应用
Cookie的Python爬虫应用 Cookie是什么 Cookie,有时也用其复数形式 Cookies,英文是饼干的意思.指某些网站为了辨别用户身份.进行 session 跟踪而储存在用户本地终端上 ...
- centos 7 安装WordPress的参考博文
安装方法: https://www.cnblogs.com/flankershen/p/7476415.html 安装完,测试不成功的解决办法: https://blog.csdn.net/u0104 ...