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 请求等异步任务.在我们请求之前以及请求之后,都需要完成一些固定的操作,比如:请求之前先从 ...
随机推荐
- C#MySQL增删改查
首先在项目中添加引用 using MySql.Data.MySqlClient; 连接字符串 private string connString="server=localhost;use ...
- this经典试题
<body> <div class="container"> <h3>输出内容</h3> <pre> var name ...
- 【转】PCA for opencv
对于PCA,一直都是有个概念,没有实际使用过,今天终于实际使用了一把,发现PCA还是挺神奇的. 在OPENCV中使用PCA非常简单,只要几条语句就可以了. 1.初始化数据 //每一行表示一个样本 Cv ...
- Laravel常用命令
php artisan make:controller BlogController php artisan make:model Blog
- 02Vs2013常用路径配置
1.设置头文件路径 项目 -> xxx属性页 -> 配置属性 -> C/C++ -> 常规 -> 附加包含目录. 2.包含 x.lib 库路径 项目 -> xxx属 ...
- jQuery发送ajax请求实现跨域访问
Java代码的话,在返回响应之前调用如下代码中的allowCrossDomainAccess()方法: /** * 允许跨域访问 */ public void allowCrossDomainAcce ...
- jquery中arrt()和prop()的区别
在jQuery中,attr()函数和prop()函数都用于设置或获取指定的属性,它们的参数和用法也几乎完全相同. 但不得不说的是,这两个函数的用处却并不相同.下面我们来详细介绍这两个函数之间的区别. ...
- IOC容器和Bean的配置实例
实验1: <!--实验1:通过IOC容器创建对象,并为属性赋值 --> <!-- 需要由IOC容器创建对象的全类名 --> <!-- 为了便于从IOC容器中获取book对 ...
- HDU - 4027 Can you answer these queries?(线段树)
给定一个长度为n的序列,m次操作. 每次操作 可以将一个区间内的所有数字变为它的根号. 可以查询一个区间内所有元素的和. 线段树的初级应用. 如果把一个区间内的元素都改为它的根号的话,是需要每个数字都 ...
- The 2018 ACM-ICPC Chinese Collegiate Programming Contest Maximum Element In A Stack
//利用二维数组模拟 #include <iostream> #include <cstdio> #include <cstring> #include <s ...