模塊編程原則:高內聚,低耦合(重復部分少),讓一個模塊有強的功能性、高的獨立性 → 單一責任制,用函數進行解耦合。
1. 函數命名規則
- 不能以數字開頭
- 可以以字母_$開頭
- 包含數字
- 小駝峰命名法
- 函數聲明一定有函數名,不然報錯
// Uncaught SyntaxError: Function statements require a function name
function () {console.log(1)
}
// 函數內 a是局部變量,b var在window上/GO,是全局變量(泄漏)
var a = b = 1
- 用表達式、字面量的形式聲明函數,test1是會被忽略的。外部不可見,內部可遞歸
// 用表達式、字面量的形式聲明函數,test1是會被忽略的
// test1() 會報錯(外部不可見)
var test = function test1() {console.log(1)test1() // 函數內部可以調用,遞歸
}
// 匿名函數表達式/函數字面量
var test = function () {console.log(1)
}
// 實參少傳
function test(a, b, c) {console.log(a, b, c)// 不報錯,c是undefined// 預編譯時第一步就處理形參 var x = undefined
}
test(1, 2)
// 實參多傳
function test(a, b) {console.log(a, b)// 不報錯 1 2
}
test(1, 2, 3)
- 函數內可獲取實參和形參的個數
// 函數內可獲取實參、形參
function test(a, b) {console.log(arguments)// 實參個數console.log(test.length)// 形參個數
}
- 實參傳了值的,函數內實參可更改 打印出 3 2
- 理解:實參和形參是映射關系,當形參改變,實參指向的堆空間的對應位置的值也改變了
- 實參未傳值的,是無法賦值的,undefined
與其他程序設計語言不同,ECMAScript 不會驗證傳遞給函數的參數個數是否等于函數定義的參數個數。開發者定義的函數都可以接受任意個數的參數(根據 Netscape 的文檔,最多可接受 255 個),而不會引發任何錯誤。任何遺漏的參數都會以 undefined 傳遞給函數,多余的函數將忽略。
- 用 arguments 對象判斷傳遞給函數的參數個數,即可模擬函數重載
// 一個函數,根據傳入實參個數的不同,做不同的事
function doAdd() {if(arguments.length == 1) {alert(arguments[0] + 5);} else if(arguments.length == 2) {alert(arguments[0] + arguments[1]);}
}doAdd(10); //輸出 "15"
doAdd(40, 20); //輸出 "60"
- arguments[1]和形參b不是一個東西,一個存在堆內存、一個存在棧內存,但有映射關系(arguments存的是指針)
- 函數內的return作用:終止和執行
- 函數內不寫return,運行時會自動加上return
- 遞歸實現階乘與斐波那契:找到規律和函數出口(函數return)
function compute(n) {if (n === 1) {return 1} else {return n * compute(n - 1)}
}
console.log('5的階乘', compute(5))
// value 1 1 2 3 5 8 13 21
// index 1 2 3 4 5 6 7
function compute(n) {if (n === 0 || n === 1) {return 1} else {return compute(n - 1) + compute(n - 2)}}
console.log('斐波那契第7項', compute(7))
2. ECMAScript補充
- ECMAScript 的函數實際上是功能完整的對象
- 在下面的形式中,每個 arg 都是一個參數,最后一個參數是函數主體(要執行的代碼)。
- 這些參數必須是字符串。
- 由于字符串的關系,這種形式寫起來有些困難,但有助于理解函數只不過是一種引用類型,它們的行為與用 Function 類明確創建的函數行為是相同的。(但是
typeof
函數的返回值是function
而不是object
) - 函數名只是指向函數對象的引用值,行為就像其他對象一樣。甚至可以使兩個變量指向同一個函數(理解函數重載)
- 所有函數都應看作 Function 類的實例。
- Function 對象也有與所有對象共享的 valueOf() 方法和 toString() 方法。這兩個方法返回的都是函數的源代碼 (原始值的基本包裝類、對象的toString方法)
var function_name = new Function(arg1, arg2, ..., argN, function_body)
function sayHi(sName, sMessage) {alert("Hello " + sName + sMessage);
}
var sayHi
=
new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");