什么是函數(shù)? 可以把函數(shù)理解成一個(gè)可以執(zhí)行的代碼塊. 函數(shù)在 JavaScript 中本身就是引用類(lèi)型. 利用函數(shù), 可以對(duì)一些代碼語(yǔ)句進(jìn)行封裝也可以對(duì)一些數(shù)據(jù)進(jìn)行隱藏(閉包)
1. 函數(shù)的創(chuàng)建
1.1 構(gòu)造方式:
函數(shù)創(chuàng)建的方式有:
- 使用Function 構(gòu)造方法來(lái)進(jìn)行創(chuàng)建
var funcName = new Function([argument1,[... argumentN]] body);
var add = new Function("x","y", "return (x+y)"); // 執(zhí)行結(jié)果 add(2,4) = 6
- 通過(guò)字面量來(lái)創(chuàng)建函數(shù)
function add(x,y){
return x+y;
}
等價(jià)于:
var add = function(x,y){
return x+y;
}
1.2 函數(shù)的參數(shù):
JavaScript 中函數(shù)的概念沒(méi)有限制參數(shù)的傳入個(gè)數(shù), 實(shí)際傳入的參數(shù)會(huì)保存在 函數(shù) 的屬性 arguments中, 然后以 index 的方式訪問(wèn)每個(gè)參數(shù). 如果方法調(diào)用時(shí)傳入的參數(shù)少于實(shí)際聲明的參數(shù),則會(huì)以 null 填充:
function printStudentInfo(name, age, sex){
var argAge = age || 18;
var sex = sex || "boy";
console.log("name: " + name + ", age = " + age + ", sex = " + sex);
if(arguments.length == 4){
console.log("hide argument : " + arguments[3]);
}
}
方法printStudentInfo各種調(diào)用情況:

2 函數(shù)作用域:
我們先看一個(gè)示例:
var str = 'global';
function funScrope(){
console.log("str = " + str);
var str = 'local'
console.log("str = " + str);
}
function funScropeForOther(){
console.log("str = " + str);
var strOther = 'local'
console.log("strOther = " + strOther);
}
執(zhí)行結(jié)果:

出現(xiàn)這種執(zhí)行結(jié)果的原因:
- 函數(shù)是在局部作用域上運(yùn)行的, 在局部作用域內(nèi)運(yùn)行的函數(shù)體可以訪問(wèn)外部的變量和函數(shù), 所以 funScropeForOther 的 str 能讀取到外部變量 "global" 值
- JavaScript的作用域是詞法作用域, 所以funScrope 在進(jìn)行詞法分析的時(shí)候, 就已經(jīng)定義了 str 變量, 只不過(guò)在 執(zhí)行 *var str = "local" * 的時(shí)候才進(jìn)行變量賦值.
var index = 0;
function forEach(){
for(var i = 0; i < 3; i++){
console.log(i);
setTimeout(function(){
console.log((index++) + " current item " + i + "\n");
}, 0);
}
}
執(zhí)行結(jié)果:
函數(shù)中使用到的 i 都為 for 執(zhí)行完后的最后一個(gè)值

3 函數(shù)的 Context 上下文 (this)
JavaScript 的函數(shù)并非一定要依附于對(duì)象, 其可以作為 一個(gè)對(duì)象的方法也可以作為另一個(gè)對(duì)象的方法. 可以通過(guò) call 或 apply 方法來(lái)修改函數(shù)的上下文, 函數(shù)中的 this 指針則為 call 或 apply 方法的第一個(gè)參數(shù)
var Tom = {name : "Tom"};
var Jerry = {name : "Jerry"};
function printName(){
console.log(this.name);
}
通過(guò) call 和 apply 調(diào)用 printName 的執(zhí)行結(jié)果為:

其中 call 和 apply 的差別為, call 方法在 this對(duì)象后面需要跟若干個(gè)方法調(diào)用所需要的參數(shù), 而 apply 第二個(gè)參數(shù)為一個(gè) array 數(shù)組, 需要的參數(shù)則全放到數(shù)組里.
4 函數(shù)的使用
函數(shù)使用的范圍:
- 將函數(shù)賦值給一個(gè)變量, 變量可以作為函數(shù)的引用
- 將函數(shù)賦值給一個(gè)對(duì)象的屬性, 函數(shù)就具有當(dāng)前對(duì)象的上下文 this
- 作為參數(shù)傳入別的函數(shù)中, 可以通過(guò) () 直接調(diào)用, 或者通過(guò) call 和 apply進(jìn)行調(diào)用
- 作為其他函數(shù)執(zhí)行的結(jié)果返回. (閉包的概念)
作為其他函數(shù)執(zhí)行的結(jié)果的示例:
function outerFunction(){
this.hideName = "hide name";
return function(){
return this.hideName;
};
}
執(zhí)行結(jié)果:
