函数


1. 函数的声明 
1.1  关键字 function 函数就是使用function命令命名的代码区块,便于反复调用。function命令后面是函数名,函数名后面是一对圆括号,里面是传入函数的参数。函 数体放在大括号里面。
//函数的声明 function test() { //方法体 }
1.2 函数表达式  除了用function命令声明函数,还可以采用变量赋值的写法。
//函数表达式 var test = function() { //方法体 }
说明 : 1.采用函数表达式声明函数时, 采用函数表达式声明函数时,function命令后面不带有函数名。 命令后面不带有函数名。 2.函数的表达式需要在语句的结尾加上分号,表示语句结束。而函数的声明在结尾的大括号后面不用加分号。总的来说,这两种声 函数的表达式需要在语句的结尾加上分号,表示语句结束。而函数的声明在结尾的大括号后面不用加分号。总的来说,这两种声 明函数的方式,差别很细微 明函数的方式,差别很细微(变量提升 变量提升),这里可以近似认为是等价的。 ,这里可以近似认为是等价的。
1.3 Function构造函数 构造函数 通过Function构造函数声明。总的来说,这种声明函数的方式非常不直观,几乎无人使用。
var add = new Function("x", "y", "return x + y"); console.log(add(1, 2));
1.4 函数的重复声明 如果多次采用function命令,重复声明同一个函数,则后面的声明会覆盖前面的声明。
function f(){ console.log(1); } f(); // 2 function f(){ console.log(2); } f(); // 2
2. 形式参数和return语句 语句
调用函数时,要使用圆括号运算符。圆括号之中,可以加入函数的参数。
function add(x,y) { return x+y; } add(1,1) // 2
3. 立即调用的函数表达式( 立即调用的函数表达式(IIFE(Immediately-Invoked Function Expression)) )
有时,我们需要在定义函数之后,立即调用该函数。这时,你不能在函数的定义之后加上圆括号,这会产生语法错误。产生这个错误的原因 是,Javascript引擎看到function关键字之后,认为后面跟的是函数定义语句,不应该以圆括号结尾。
function(){ /* code */ }();
// SyntaxError: Unexpected token (
解决方法 : 圆括号前面的部分不是函数定义语句,而是一个表达式,可以对此进行运算。 圆括号前面的部分不是函数定义语句,而是一个表达式,可以对此进行运算。
(function(){ /* code */ }()); // 或者 (function(){ /* code */ })();
注意,上面的两种写法的结尾,都必须加上分号。
4. 第一等公民 
JavaScript的函数与其他数据类型处于同等地位,可以使用其他数据类型的地方就能使用函数。比如,可以把函数赋值给变量和对象的属性,也 可以当作参数传入其他函数,或者作为函数的结果返回。这表示函数与其他数据类型的地方是平等,所以又称函数为第一等公民。
function add(x, y) { return x + y; } // 将函数赋值给一个变量 var fn = add; console.log(fn(1, 2)); // 将函数作为参数和返回值 function operator(fn) { return fn; } console.log(operator(add)(1, 2));
5. 函数名的提升
JavaScript引擎将函数名视同变量名,所以采用function命令声明函数时,整个函数会被提升到代码头部。所以,下面的代码不会报错。
var sum = add(1, 2); console.log(sum);
function add(x, y) { return x + y; }
表面上,上面代码好像在声明之前就调用了函数 表面上,上面代码好像在声明之前就调用了函数add。但是实际上,由于 。但是实际上,由于“变量提升 变量提升”,函数 ,函数f被提升到了代码头部,也就是在调用之 被提升到了代码头部,也就是在调用之 前已经声明了。但是,如果采用赋值语句定义函数, 前已经声明了。但是,如果采用赋值语句定义函数,JavaScript就会报错。 就会报错。
var sum = add(1, 2); console.log(sum); var add = function (x, y) { return x + y; } //Uncaught TypeError: add is not a function
如果同时采用 如果同时采用function命令和赋值语句声明同一个函数,最后总是采用赋值语句的定义。 命令和赋值语句声明同一个函数,最后总是采用赋值语句的定义。
var fn = function() { console.log ("1"); }; function fn() { console.log("2"); } fn(); // 1
6. 函数的属性和方法 
6.1 name属性 :返回紧跟在 返回紧跟在function关键字之后的那个函数名。 关键字之后的那个函数名。
function fn1() {} console.log(fn1.name); var fn2 = function() {}; console.log(fn2.name); var fn3 = function fn3() {}; console.log(fn3.name);
6.2 length属性 :返回函数定义中参数的个数。 返回函数定义中参数的个数。
function fn(x, y) {} console.log(fn.length);
7. 函数作用域 
7.1 定义  作用域(scope)指的是变量存在的范围。Javascript只有两种作用域:一种是全局作用域,变量在整个程序中一直存在;另一种是函数作用域, 变量只在函数内部存在。 (1) 在函数外部声明的变量就是全局变量(global variable),它可以在函数内部读取。 (2) 在函数内部定义的变量,外部无法读取,称为“局部变量”(local variable)。 (3) 函数内部定义的变量,会在该作用域内覆盖同名全局变量。
7.2 函数内部的变量提升 与全局作用域一样,函数作用域内部也会产生“变量提升”现象。var命令声明的变量,不管在什么位置,变量声明都会被提升到函数体的头部。 7.3 函数本身的作用域 函数本身的作用域 函数本身也是一个值,也有自己的作用域。它的作用域绑定其声明时所在的作用域。
var a = 1; var fn = function() { console.log(a); }; function fn1() { var a = 2; fn(); } fn1(); //1
8. 参数
8.1 概述 函数运行的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部数据就叫参数。
function square(x) { return x * x; } square(2); //4 square(3); //9
8.2 传递方式  JavaScript的函数参数传递方式是传值传递(passes by value),这意味着,在函数体内修改参数值,不会影响到函数外部。
//原始数据类型 var a = 1; function fn(a) { a = 3; } fn(a); console.log(a); //1 //引用类型 var arr = [1, 2, 3]; function fn1(arr) { arr = [4, 5, 6]; }
fn1(arr); console.log(arr); //[1, 2, 3]
注意  , 虽然参数本身是传值传递,但是对于复合类型的变量来说,属性值是传址传递( 虽然参数本身是传值传递,但是对于复合类型的变量来说,属性值是传址传递(pass by reference),也就是说,属性值是通过 ),也就是说,属性值是通过 地址读取的。所以在函数体内修改复合类型变量的属性值,会影响到函数外部。 地址读取的。所以在函数体内修改复合类型变量的属性值,会影响到函数外部。
//修改对象的属性值 var obj = { attr : 1 }; function fn(obj) { obj.attr = 2; } console.log(obj.attr); //修改数组的元素值 var arr = [1, 2, 3]; function fn(arr) { arr[0] = 4; arr[1] = 5; arr[2] = 6; } fn(arr); console.log(arr.toString());
8.3 arguments对象 1) 由于JavaScript允许函数有不定数目的参数,所以我们需要一种机制,可以在函数体内部读取所有参数。这就是arguments对象的由来。 2) arguments对象包含了函数运行时的所有参数,arguments[0]就是第一个参数,arguments[1]就是第二个参数,依次类推。这个对象只有在函 数体内部,才可以使用。 3) 可以通过arguments对象的length属性,判断函数调用时到底带几个参数。

posted @ 2016-05-02 23:28  霸气侧漏小红花  阅读(256)  评论(0编辑  收藏  举报