美文网首页
第七章 函数表达式

第七章 函数表达式

作者: dudu_du | 来源:发表于2017-06-19 14:52 被阅读0次

定义函数的方式有两种:

  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对象

相关文章

  • js - 函数表达式

    第七章 函数表达式 1. 创建函数两种方法 函数表达式特征 1,函数声明: 特征: 函数声明提升,意思执行代码前会...

  • 第七章 函数表达式

    第七章 函数表达式 问答 1. 函数声明的语法是? 2. 函数表达式(匿名函数)的语法是? 3. 以下递归语句是否...

  • javascript高级程序设计(第7章) -- 函数表达式

    第七章:函数表达式 本章内容: 函数表达式的特征 使用函数实现递归 使用闭包定义私有变量 定义函数的方式有两种,一...

  • 2020-01-09:第七章:函数表达式(闭包)

    第七章:函数表达式 函数表达式是js中一个非常强大但又让人困惑的特性,我们前面提到过,函数声明有两种方法:函数声明...

  • 第七章 Caché 函数大全 $CHAR 函数

    第七章 Caché 函数大全 $CHAR 函数 将表达式的整数值转换为相应的ASCII或Unicode字符。 大纲...

  • 《JavaScript高级程序设计》之笔记五

    第七章 函数表达式 1. 定义函数的两种方法 : 2. 递归 : 递归函数是在一个函数通过名字调用自身的情况下构成...

  • 07 | 读JavaScript 高程

    这是第七章函数表达式,这一章涉及函数预编译,闭包,作用域链内容。函数涉及内容繁多。 前情提要 02-1 | 读Ja...

  • 07-1 | 读JavaScript 高程

    这是第七章函数表达式,这一章涉及函数预编译,闭包,作用域链内容。函数涉及内容繁多。今天来看作用域链。 在 06-2...

  • 函数与作用域

    函数声明和函数表达式有什么区别 函数声明 函数表达式 区别 函数表达式结束后需要加;表示声明变量结束。 函数表达式...

  • 函数

    函数声明和函数表达式有什么区别 函数声明 函数表达式 函数声明和函数表达式的区别: 函数声明必须给定函数名称,函数...

网友评论

      本文标题:第七章 函数表达式

      本文链接:https://www.haomeiwen.com/subject/jbvgqxtx.html