作者:張耀國(igorzhang)
函數(shù)
函數(shù)就是把完成特定的功能的代碼段封裝起來,給該功能起一個(gè)名字(函數(shù)名),封裝好該功能后,哪里需要調(diào)用該功能就在哪里去調(diào)用即可,函數(shù)可以在任何時(shí)間任何地點(diǎn)進(jìn)行調(diào)用。
使用函數(shù)的好處:
1、是程序變得簡潔明了
2、有利于后期的代碼維護(hù)
3、可以提高程序的開發(fā)效率
4、提高了代碼的復(fù)用性
總結(jié):之前不使用函數(shù)的情況下,JS代碼必須按照順序去執(zhí)行,并且執(zhí)行代碼的那部分和執(zhí)行時(shí)間都是不可控的。但是聲明函數(shù)后,瀏覽器不會(huì)直接去執(zhí)行它,只有我們?cè)谙胧褂盟臅r(shí)候才會(huì)去執(zhí)行,很靈活。
函數(shù)的分類:
1、系統(tǒng)自帶的函數(shù):alert() parseInt()...
2、自定義的函數(shù):根據(jù)自己需求定義的函數(shù)。
自定義函數(shù)的使用步驟:
1、聲明一個(gè)函數(shù)(定義)。
2、調(diào)用這個(gè)函數(shù)(在任何時(shí)候,任何地方都可以調(diào)用)
聲明函數(shù)的語法如下:
用function關(guān)鍵字去聲明一個(gè)函數(shù)
function 函數(shù)名字(參數(shù)1,參數(shù)2,……) {//參數(shù)根據(jù)需求可有可無
//執(zhí)行函數(shù)的內(nèi)容
return 返回值; //根據(jù)需求返回值可有可無.
}
調(diào)用函數(shù)的語法如下:
函數(shù)名字(參數(shù)值1,參數(shù)值2.……); //參數(shù)根據(jù)該函數(shù)聲明時(shí)是否有參數(shù)而定
總結(jié)一下:
1、function關(guān)鍵字,定義函數(shù)的關(guān)鍵字,必須有!
2、函數(shù)名(符合標(biāo)識(shí)符的定義標(biāo)準(zhǔn))。必須有(過后我們會(huì)學(xué)習(xí)匿名函數(shù),情況會(huì)特殊一下)!
3、參數(shù)列表,在聲明的時(shí)候--就是一些標(biāo)識(shí)符,根據(jù)情況可由可無。如果有的話,有一個(gè)參數(shù)或者多個(gè)參數(shù)。在采用的時(shí)候--是具體要傳入的值,根據(jù)情況可有可無。
4、函數(shù)體{},函數(shù)內(nèi)就是將來要執(zhí)行的代碼,返回值根據(jù)情況可有可無。
printKiss();//在這里能調(diào)用的原因是:JS幫我們做了一個(gè)聲明提前。
//聲明一個(gè)無參數(shù),無返回值的函數(shù)。
//函數(shù)的功能是打印“要親親,要抱抱,要舉高高”
function printKiss () {
console.log("要親親,要抱抱,要舉高高。"); //函數(shù)不調(diào)用是不會(huì)走這段代碼的。
}
printKiss(); //調(diào)用函數(shù),想調(diào)用多少次都行。
printKiss();
printKiss();
//聲明一個(gè)無參數(shù),有返回值的函數(shù)。
//函數(shù)的功能,獲得“我們是H5-10期的好孩子?!边@句話
function getClassName () {
return "我們是H5工程師。"; //return關(guān)鍵字表示立即停止函數(shù)的運(yùn)行,并且返回相應(yīng)的內(nèi)容。暫時(shí)這個(gè)學(xué)習(xí)階段,我們只會(huì)返回一些基本類型,例如數(shù)值型,字符串型,布爾型等,高級(jí)階段return還可以返回對(duì)象類型和另外一個(gè)函數(shù)。
}
var className = getClassName();//因?yàn)楹瘮?shù)有返回值,所以調(diào)用的時(shí)候用一個(gè)變量去接受該函數(shù)的返回值。
console.log(className); // 此時(shí)控制臺(tái)輸出“我們是H5工程師”
//return可以立即停止函數(shù)的運(yùn)行,類似于循環(huán)結(jié)構(gòu)中的break關(guān)鍵字。return可以給返回值,也可以不給。但不管給不給返回值,只要寫return了,就可以立刻停止函數(shù)的運(yùn)行。
function testFn() {
var a =10;
var b = 20;
if(b > a) {
//return b; //會(huì)返回b的值,并且中斷函數(shù)的運(yùn)行下面代碼都不會(huì)執(zhí)行。
return "那肯定不能執(zhí)行啊";//這里可以有返回值,也可以不寫返回值,根據(jù)自己需求而定。
}
console.log("你覺得我這段代碼能執(zhí)行嗎?");
}
var maxNum = testFn();//函數(shù)的調(diào)用,并且結(jié)接受返回值給maxNum,如果函數(shù)沒有返回值的話,則接受后則是underfined
console.log(maxNum); // 控制臺(tái)輸出“那肯定不能執(zhí)行啊” ,說明程序滿足if條件后被return打斷了。
//函數(shù)體內(nèi),也可以調(diào)用另外一個(gè)函數(shù)
function fn1 () {
// var name = fn2(); //函數(shù)內(nèi)調(diào)用另外一個(gè)函數(shù),可以再函數(shù)內(nèi)直接調(diào)用
// console.log(name);
// return name + "耀國國";
return fn2() + "耀國國"; // 也可以調(diào)用后作為返回值輸出
}
function fn2 () {
return "給fn1函數(shù)提供的數(shù)據(jù)!";
}
var str = fn1(); //想執(zhí)行以上代碼,必須要先調(diào)用fn1函數(shù)。
console.log(str); // 此時(shí)控制臺(tái)就輸出 “給fn1函數(shù)提供的數(shù)據(jù)!耀國國”
匿名函數(shù)
匿名函數(shù):“沒有函數(shù)名:。將來會(huì)用到真正的”沒有函數(shù)名“的函數(shù),例如:函數(shù)作為回調(diào)函數(shù)的時(shí)候,作為返回值的時(shí)候。
匿名函數(shù)和正常函數(shù)做的事情是一樣的,都需要聲明和調(diào)用。
//這樣直接暴露在程序外面是錯(cuò)誤的,除非將來學(xué)習(xí)到高階函數(shù)的時(shí)候,作為返回值或者參數(shù)是可以的。
function () {
console.log("我是一個(gè)匿名函數(shù)");
}
fn1()
注意:匿名函數(shù)這種方式,不支持聲明提前。所以不要再還沒有聲明函數(shù)的時(shí)候調(diào)用,會(huì)報(bào)錯(cuò)--fn1 is not a function
//聲明一個(gè)匿名函數(shù)
var fn1 = function () {
console.log("我是一個(gè)匿名函數(shù)");
}
fn1 () ;//和正常函數(shù)一樣,想使用必須調(diào)用一下才行
函數(shù)的參數(shù)
函數(shù)的參數(shù)分為形參和實(shí)參。
形參:函數(shù)聲明時(shí)用的。
實(shí)參:函數(shù)調(diào)用時(shí)用的。
形參其語法如下:
function fn (str) { //其中str就是形參,符合標(biāo)識(shí)符聲明的規(guī)則,過后調(diào)用fn后傳進(jìn)來的實(shí)參是什么值,這個(gè)str就代表那個(gè)值。
console.log(str); //在函數(shù)體中,形參就和普通變量一樣,該如何使用就如何使用。
}
實(shí)參語法如下:
fn(123); //123 就是實(shí)參(說白了就是具體的值),給函數(shù)聲明時(shí)的形參用的。
注意:在大部分編程語言中。實(shí)參的個(gè)數(shù)與形參的個(gè)數(shù)和類型是相同的。但是對(duì)于JS而言,不會(huì)檢查實(shí)參和形參的個(gè)數(shù)和類型。
調(diào)用函數(shù),傳參相當(dāng)于賦值,將實(shí)參的值賦值給形參。
聲明一個(gè)帶參數(shù)的函數(shù)
function fn (name) { //name就是形參,一會(huì)調(diào)用的時(shí)候就會(huì)賦值給她
console.log("大家好,我叫:" + name);
}
fn("張耀國");
fn("羊羊羊");
聲明一個(gè)帶多個(gè)參數(shù)的函數(shù)
function fn2 (name,age,sex) { //聲明多個(gè)參數(shù),參數(shù)之間用“,”隔開。
console.log("名字是:" + name + "\n年齡是:" + age + "\n性別是:" + sex);
}
fn2('張耀國','18','男');
聲明帶多個(gè)形參的函數(shù),但是實(shí)參個(gè)數(shù)不確定
function fn3 (a,b,c) { //聲明的時(shí)候是3個(gè)形參
console.log(a);
console.log(b);
console.log(c);
}
fn3(); //不傳任何參數(shù) 不會(huì)報(bào)錯(cuò),最多是形參是underfined.
fn3(20); //傳一個(gè)實(shí)參的話,就會(huì)賦值給第一個(gè)形參,后面如果有其他形參的話參數(shù)值是underfined
fn3(12,23,34,45,56,67); //穿入的實(shí)參個(gè)數(shù)大于形參個(gè)數(shù),只去依次匹配形參,多余的沒用
聲明時(shí)不給參數(shù)
function fn4 () { //聲明的時(shí)候沒有給任何形參
//每個(gè)函數(shù)體內(nèi)都有一個(gè)arguments對(duì)象(參數(shù)數(shù)組)里面存貯了傳進(jìn)來的所有參數(shù))
//獲取第一個(gè)參數(shù)的語法是arguments[0],從0開始,獲取第二個(gè)參數(shù)arguments[1]...依次類推
console.log(arguments[0]);
console.log(arguments[1]);
//通過arguments.length 獲取參數(shù)的個(gè)數(shù)
console.log(arguments.length);
}
函數(shù)的重載
所謂函數(shù)的重載,是指大部分面向?qū)ο笳Z言中的概念,指的是函數(shù)名字相同,但參數(shù)不同(參數(shù)個(gè)數(shù)不同,參數(shù)類型不同)。注意:在JS中沒有函數(shù)重載的概念,如果出現(xiàn)函數(shù)名字相同的情況,那么后面的會(huì)覆蓋掉前面的函數(shù)。
function sayHello(name){
console.log("我的名字叫做:" + name );
}
//函數(shù)名字和上面的函數(shù)一樣,那么不會(huì)實(shí)現(xiàn)重載,而會(huì)覆蓋掉上面的函數(shù)。
function sayHello(name,age){
console.log("我的名字叫做:" + name + ",年齡:" +age);
}
sayHello("zyg"); // 函數(shù)名相同,只調(diào)用第二個(gè)函數(shù)
sayHello("aaa",19);
遞歸函數(shù)
遞歸函數(shù):所謂遞歸函數(shù),就是函數(shù)本身調(diào)用自己,通過改變步進(jìn)條件,來終止函數(shù)的運(yùn)行。
補(bǔ)充:一般用循環(huán)的解決的問題,用遞歸也能解決。
遞歸寫法
function fn2(num){
//最終停止遞歸調(diào)用的臨界條件,當(dāng)num等于0時(shí),程序結(jié)束
if(num == 0){
return;
}
console.log(num);
num--;
fn2(num); //遞歸調(diào)用
}
fn2(5); // 實(shí)參傳入5,函數(shù)運(yùn)行后控制臺(tái)會(huì)分五次輸出5,4,3,2,1
聲明一個(gè)函數(shù),傳入一個(gè)數(shù)值,實(shí)現(xiàn)這個(gè)數(shù)值的階乘,所謂階乘,例如5的階乘就是 5 x 4 x 3 x 2 x 1 特殊:0的階乘也是1
遞歸用到的公式(num的階乘):num * (num - 1)的階乘
function fn3(num){
if(num == 1){
return 1;
}
return num * fn3(num - 1);
// 隨著遞歸的調(diào)用,最終調(diào)用結(jié)果相當(dāng)于 5 * 4 * 3 * 2 *1
}
console.log(fn3(5));