第七章 函数表达式

定义函数的方式有两种:

  1. 函数声明
    重要特征就是函数声明提升,意思是在执行代码之前会先读取函数声明。这就意味着可以把函数声明放在调用它的语句后面。
  2. 函数表达式
    函数表达式有几种不同的语法形式。下面是最常见的一种形式。
    <pre>
    var functionName = function(arg0, arg1, arg2){
    //函数体
    };
    </pre>
    函数表达式与其他表达式一样,在使用前必须先赋值。
    <pre>
    sayHi(); //错误:函数还不存在
    var sayHi = function(){
    alert("Hi!");
    };
    </pre>

理解函数提升的关键,就是理解函数声明和函数表达式之间的区别。
<pre>
//不要这样做!
if(condition){
function sayHi(){
alert("Hi!");
}
}
else {
function sayHi(){
alert("Yo!");
}
}
</pre>
不过,如果是使用函数表达式,那就没有什么问题了。
<pre>
//可以这样做
var sayHi;
if(condition){
sayHi = function(){
alert("Hi!");
};
}
else {
sayHi = function(){
alert("Yo!");
};
}
</pre>

7.1 递归

arguments.callee 是一个指向正在执行的函数的指针,因此可以用它来实现对函数的递归调用
<pre>
function factorial(num){
if(num<=1){
return 1;
}
else{
return numarguments.callee(num-1);*
}
}
</pre>

但是在严格模式下,不能通过脚本访问arguments.callee,访问这个属性会导致错误。不过,可以使用命名函数表达式来达成相同的结果。
<pre>
var factorial = (function f(num){
if(num <= 1){
return 1;
}
else{
return num * f(num - 1);
}
})
</pre>

7.2 闭包

闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部常见另一个函数。

7.2.1 闭包与变量

  • 作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值。
  • 闭包所保存的是整个变量对象,而不是某个特殊的变量。

<pre>
function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(){
return i;
};
}
return result;
}
</pre>

这个函数会返回一个函数数组。表面上看,似乎每个函数都应该返自己的索引值,即位置 0 的函数返回 0,位置 1 的函数返回 1,以此类推。但实际上,每个函数都返回 10。因为每个函数的作用域链中都保存着 createFunctions() 函数的活动对象,所以它们引用的都是同一个变量 i 。当createFunctions() 函数返回后,变量 i 的值是 10,此时每个函数都引用着保存变量 i 的同一个变量对象,所以在每个函数内部 i 的值都是 10。

但是,我们可以通过创建另一个匿名函数强制让闭包的行为符合预期。
<pre>
function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(num){
return function(){
return num;
};
}(i);
}
return result;
}
</pre>

在重写了前面的 createFunctions() 函数后,每个函数就会返回各自不同的索引值了。在这个版本中,我们没有直接把闭包赋值给数组,而是定义了一个匿名函数,并将立即执行该匿名函数的结果赋给数组。这里的匿名函数有一个参数 num ,也就是最终的函数要返回的值。在调用每个匿名函数时,我们传入了变量 i 。由于函数参数是按值传递的,所以就会将变量 i 的当前值复制给参数 num 。而在这个匿名函数内部,又创建并返回了一个访问 num 的闭包。这样一来, result 数组中的每个函数都有自己num 变量的一个副本,因此就可以返回各自不同的数值了。

7.2.2 关于this对象

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.定义函数的方式: ①函数声明(其重要特征是函数声明提升,可以把函数声明放在调用它的语句后面): functio...
    张果果阅读 233评论 0 0
  • 定义函数的方式有两种:函数声明和函数表达式。 函数声明的一个重要特征就是函数声明提升,意思是在执行代码前会先读取函...
    oWSQo阅读 684评论 0 0
  • 效果 思路 先绘制刻度和文字,通过旋转画布来操作 绘制指针 绘制中心原点 遇到的问题 怎么实时刷新时间 让指针转起...
    木木公白阅读 1,130评论 2 1
  • 为了不被困于永恒的当下,我们要争取活在未来。对未来某件事的预测,如果按照预想的结果来行事,所以在到底这个结果之前,...
    雷哥复利笔记阅读 288评论 0 0
  • 刚刚读完了《巴菲特之道》一书,因为好多策略之前就看过了,所以并没有感觉有多大的震撼!不过本书好多细节还是很让人受益...
    甄峸阅读 2,690评论 0 2