多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## 7.1 函数概述 ### 7.1.1 函数声明(定义) **1. JavaScript有三种方法,可以声明一个函数。** * **function命令** function命令声明的代码区块,就是一个函数。格式为:`function 函数名(参数){ 函数体 }` ~~~ function print(s) { console.log(s); } ~~~ 上面的代码命名了一个print函数,以后使用print()这种形式,就可以调用相应的代码。这叫做**函数的声明(Function Declaration)。** * **函数表达式** 除了用function命令声明函数,还可以采用变量赋值的写法。 ~~~ var print = function(s) { console.log(s); }; ~~~ 这种写法将一个匿名函数赋值给变量。这时,这个匿名函数又称函**数表达式(Function Expression)**,因为赋值语句的等号右侧只能放表达式。 采用函数表达式声明函数时,function命令后面不带有函数名。如果加上函数名,该函数名只在函数体内部有效,在函数体外部无效。 * **Function构造函数** Function()函数定义还可以通过Function()构造函数来定义 ~~~ var f=new Function('x','y','return x+y'); 等价于 var f=function(x,y){ return x+y; } ~~~ 除了最后一个参数是函数体外,前面的其他参数都是函数的形参。如果函数不包含任何参数,只须给构造函数简单的传入一个字符串---函数体---即可。 不过,Function()构造函数在实际编程中很少会用到。 注意:根据ECMAScript的规范,不得在**非函数的代码块**中声明函数,最常见的情况就是if和try语句。 **2. 函数声明提升** 就像变量的“被提前”一样,函数声明语句也会“被提前”到外部脚本或外部函数作用域的顶部,所以以这种方式声明的函数,可以被在它定义之前出现的代码所调用。 ~~~ f() function f(){} 其实JavaScript是这样解释的: function f(){} f() ~~~ 注意:在函数提升中,函数体也会跟着提升(不像变量一样,只会提升变量声明),这也是我们可以引用后面声明的函数的原因。 此外,以表达式定义的函数并没有“被提前”,而是以变量的形式“被提前”。 ~~~ f(); var f = function (){}; // TypeError: f is not a function ~~~ 变量其实是分为声明,赋值两部分的,上面的代码等同于下面的形式 ~~~ var f; f(); f = function() {}; ~~~ 调用f的时候,f只是被声明了,还没有被赋值,等于undefined,所以会报错。 ### 7.1.2 函数命名 任何合法的JavaScript标识符都可以用做一个函数的名称。 函数名称通常是动词或以动词为前缀的词组。 通常函数名的第一个字符为小写。当函数名包含多个单词时,可采取下划线法,比如:like_this();也可以采取**驼峰法**,也就是除了第一个单词之外的单词首字母使用大写字母,比如:likeThis(); ### 7.1.3 函数调用 构成函数主体的JavaScript代码在定义时并不会执行,只有调用该函数,它们才会执行。 有4种方式调用JavaScript函数 **1.函数名调用** 函数可以通过函数名来调用,后跟一对圆括号和参数(圆括号中的参数如果有多个,用逗号隔开) ~~~ function test(){}; test(); ~~~ **2.方法调用** ~~~ var o = { f: function(){} } o.f(); ~~~ **3. 构造函数调用** 如果函数或者方法调用之前带有关键字new,它就构成构造函数调用。 凡是没有形参的构造函数调用都可以省略圆括号(但不推荐)。 ~~~ var o=new Object(); var o=new Object; ~~~ **4.通过它们的call()和apply()方法间接调用** ### 7.1.4 函数参数 **查看3.7节** ### 7.1.5 递归 递归函数是在一个函数中通过名字调用资深的情况下构成的 ~~~ function factorial(num)[ if (num <= 1){ return 1; }else{ return num * factorial(num - 1); } } ~~~ `arguments.callee`是一个指向正在执行的函数的指针,可用于实现对函数的递归调用。 ~~~ function factorial(num)[ if (num <= 1){ return 1; }else{ return num * arguments.callee(num - 1); } } ~~~ 严格模式下,不能访问arguments.callee,可以使用**命名函数表达式**来达成结果。 ~~~ var factorial = (function f(num)[ if (num <= 1){ return 1; }else{ return num * f(num - 1); } }); ~~~