JavaScript快速入門-06-函數(shù)

6 函數(shù)

6.1 函數(shù)定義

? ? 函數(shù)可以封裝語句,然后在任何地方、任何時間執(zhí)行。JavaScript中的函數(shù)使用function關(guān)鍵字聲明,主要由函數(shù)名、函數(shù)參數(shù)函數(shù)體組成。其基本語法和聲明如下所示:

  • 方式一:
function functionName(arg0, arg1,...,argN) {
    statements
}
  • 方式二:
let variable=function(arg0, arg1,...,argN) {
    statements
}
  • 方式三:
let variable=(arg0, arg1,...,argN) => {
    statements
}
  • 如果函數(shù)無返回值,則不需要return語句,如果有返回值,則需要return語句
  • 在碰到return語句后,則立即返回,后續(xù)語句不再執(zhí)行

? ? 示例如下所示:

// 無返回值函數(shù)
function hello(name){
    console.log("Hello ,",name);
}
// 存在返回值函數(shù)
function sum(number1,number2){
    return number1+number2;
}

// 遇到return語句,提前返回
function testReturn(age){
   return "test return ";
   console.log("age is:",age);

}

// 使用函數(shù)表達(dá)式定義函數(shù)
let diff=function(number1,number2){
    return number1-number2
}

// 箭頭函數(shù)
let mul=(number1,number2) =>{
    return number1*number2;
}

hello("Surpass");
console.log("sum is :",sum(7,18));
console.log(testReturn(18));
console.log("diff is:",diff(7,18));
console.log("mul is:",mul(7,18));

輸出結(jié)果如下所示:

Hello , Surpass
sum is : 25
test return
diff is: -11
mul is: 126

6.2 箭頭函數(shù)

? ? 箭頭函數(shù)實(shí)例化的函數(shù)對象與正式的函數(shù)表達(dá)式創(chuàng)建的函數(shù)對象行為是相同的。任何可以使用函數(shù)表達(dá)式的地方,都可以使用箭頭函數(shù)。需要注意事項(xiàng)如下所示:

  • 1、在僅有一個參數(shù)時,可以省略括號,以下兩種寫法完全等效:
let absValue1=(x)=>{return Math.abs(x);};
let absValue2=x=>{return Math.abs(x);};
  • 2、當(dāng)沒有參數(shù)時,括號不能省略
let getRandomNumber=()=>{return Math.random()*10;};
  • 3、多個參數(shù)也需要括號
let div=(a,b)=>{
    if(b!=0){
        return a/b;
    }
    else{
        return Infinity;
    }
};
  • 4、大括號省略注意事項(xiàng):

箭頭函數(shù)也可以不使用大括號,但這樣會改變函數(shù)的行為。使用大括號就說明包含函數(shù)體,即可以在一個函數(shù)中包含多條語句,跟常規(guī)函數(shù)一樣。如果不使用大括號,則箭頭后面就只能有一行代碼,如一個表達(dá)式、賦值操作等。而且,省略大括號會隱式返回這行代碼的值。

? ? 示例代碼如下所示:

// 以下兩種寫法都有效
let power1=(x)=>{return x**2;};
let power2=x=>x**2;

console.log("power1 is:"+power1(2)+"\npower2 is:"+power2(2));

// 進(jìn)行賦值操作
let personInfo={};
let setPersonInfoName=(name)=>personInfo.name=name;
setPersonInfoName("Surpass");
console.log("personInfo is:",personInfo);

// 無效寫法
let sum=(number1,number2)=> return number1+number2;

? ? 箭頭函數(shù)雖然語法簡潔,但也有很多場合不適用。箭頭函數(shù)不能使用arguments、super 和new.target,也不能用作構(gòu)造函數(shù)。此外,箭頭函數(shù)也沒有prototype屬性

6.3 函數(shù)名

? ? 因?yàn)?strong>函數(shù)名就是指向函數(shù)的指針,所以它們跟其他包含對象指針的變量具有相同的行為。即一個函數(shù)可以有多個名稱,如下所示:

function sum(number1,number2){
    return number1+number2;
}

console.log("Sum is: ",sum(10,18)); // 28

let refSum=sum;
console.log("refSum is: ",refSum(10,18)); // 28

sum=null;
console.log("refSum is: ",refSum(10,18)); // 28

? ? 以上代碼定義了sum()的函數(shù),并將sum賦值給refSum,使用不帶括號的函數(shù)名會訪問函數(shù)指針,并不會執(zhí)行函數(shù)。此時,refSum和sum都指向同一個函數(shù)。調(diào)用refSum()也可以返回結(jié)果。再將sum賦為null之后,就切斷了它與函數(shù)之間的關(guān)聯(lián),所以refSum()依然可以照常調(diào)用。

6.4 函數(shù)參數(shù)

? ? 在JavaScript中,函數(shù)不關(guān)心傳入的參數(shù)個數(shù)、數(shù)據(jù)類型。其函數(shù)參數(shù),在內(nèi)部表現(xiàn)一個數(shù)組,因此函數(shù)調(diào)用時都會接收到一個數(shù)組,函數(shù)并不關(guān)心數(shù)組中包含什么。

1.定義函數(shù)時,聲明有兩個參數(shù),在調(diào)用時并不一定就需要傳入兩個參數(shù),也可以傳一個,兩個,三個或不傳,解釋器也并不會報(bào)錯。
2.在使用function關(guān)鍵字定義(非箭頭)函數(shù),可以在函數(shù)內(nèi)部訪問arguments對象,從中獲取傳入的每個參數(shù)值

// 使用參數(shù)一
function hello_1(name,message){
    console.log("call function ",hello_1.name);
    return "Hello"+name+message;
}
// 使用參數(shù)二:arguments
function hello_2(){
    console.log("call function ",hello_2.name);
    console.log("input para length is:",arguments.length);
    return "Hello"+arguments[0]+arguments[1];
}

console.log(hello_1(" Surpass"," Welcome to Shanghai"));
console.log(hello_2(" Surpass"," Welcome to Shanghai"));

輸出結(jié)果如下所示:

call function  hello_1
Hello Surpass Welcome to Shanghai
call function  hello_2
input para length is: 2
Hello Surpass Welcome to Shanghai

? ? 在函數(shù)中,arguments對象可以跟參數(shù)一起使用,如下所示:

function add(number1,number2){
   let paraLength=arguments.length;
   if (paraLength == 1){
       return number1;
   } else if (paraLength ==2 ){
      return arguments[0]+number2;
   } else {
       let sum=0;
       for(let item of arguments){
          sum+=item;
       }
       return sum;
   }
}

console.log("result is:",add(1));
console.log("result is:",add(1,2));
console.log("result is:",add(1,2,3));

輸出結(jié)果如下所示:

result is: 1
result is: 3
result is: 6

如果函數(shù)是箭頭函數(shù),則傳入的參數(shù)不能再使用arguments關(guān)鍵字訪問,而只能通過定義的參數(shù)名稱來訪問

6.5 沒有重載

? ? JavaScript不像Java/C#等,存在函數(shù)重載功能。因?yàn)樵贘avaScript中函數(shù)不一定有函數(shù)名稱,參數(shù)可以是0個或多個,所以自然就沒有重載功能。如果在JavaScript中定義了兩個同名函數(shù),則后面定義的函數(shù)會覆蓋前面定義的函數(shù)。示例如下所示:

function sum(){
    return arguments[0]+28;
}

function sum(){
    return arguments[0]+128;
}

let result=sum(100);
console.log("result is:",result) // 228

6.6 參數(shù)默認(rèn)值

? ? 在ECMAScript5.1 及以前,默認(rèn)參數(shù)值為undefined,而在ECMAScript 6 之后,則可以支持顯式定義默認(rèn)參數(shù)了,如下所示:

  • 1.給參數(shù)傳undefined 相當(dāng)于沒有傳值,好處是可以利用多個獨(dú)立的默認(rèn)值
function hello(name="Surpass",message=" Welcome"){
    return `Hello  ${name} ${message}`;
}

console.log(hello()); // Hello Surpass  Welcome
console.log(hello("Kevin","Welcome to Shanghai")); // Hello Kevin Welcome to Shanghai
console.log(hello(undefined,"Welcome to Shanghai")); // Hello Surpass Welcome to Shanghai
  • 2.在使用默認(rèn)參數(shù)時,arguments 對象的值不反映參數(shù)的默認(rèn)值,只反映傳給函數(shù)的參數(shù),,修改命名參數(shù)也不會影響arguments 對象,它始終以調(diào)用函數(shù)時傳入的值為準(zhǔn)
function hello(name="Surpass",message=" Welcome"){
    name="Kevin";
    return `Hello  ${arguments[0]} ${message}`;
}

console.log(hello()); // Hello  undefined  Welcome
console.log(hello("Kevin","Welcome to Shanghai")); // Hello Kevin Welcome to Shanghai
  • 3.默認(rèn)參數(shù)值并不限于原始值或?qū)ο箢愋?,也可以使用調(diào)用函數(shù)返回的值
let name=["Surpass","Kevin","Tina","Jeniffer"];
let city=["Shanghai","Wuhan","Nanjing","Suzhou"];
let nameIndex=0,cityIndex=0;

function getCity(){
    // 每次調(diào)用后遞增
    return city[cityIndex++];
}

function getName(){
  return name[nameIndex++];
}

function hello(name=getName(),message=getCity()){
   return `Hello ${name},Welcome ${message}`;
}

for (let i = 0; i < city.length; i++) {
    console.log(hello());
}

輸出結(jié)果如下所示:

Hello Surpass,Welcome Shanghai
Hello Kevin,Welcome Wuhan
Hello Tina,Welcome Nanjing
Hello Jeniffer,Welcome Suzhou

函數(shù)的默認(rèn)參數(shù)只有在函數(shù)被調(diào)用時才會求值,不會在函數(shù)定義時求值

  • 4.箭頭函數(shù)同樣也可以使用默認(rèn)參數(shù),但在僅有一個參數(shù)時,則不能省略括號
let hello=(name="Surpass")=>{return `Hello ${name}`;}

console.log(hello()); // Hello Surpass 
console.log(hello("Kevin")); // Hello Kevin

6.7 參數(shù)擴(kuò)展和收集

? ? ECMAScript 6 新增了擴(kuò)展操作符,使用它可以非常簡潔地操作和組合集合數(shù)據(jù)。擴(kuò)展操作符最有用的場景就是函數(shù)定義中的參數(shù)列表。既可以用于調(diào)用函數(shù)時傳參,也可以用于定義函數(shù)參數(shù)。

6.7.1 擴(kuò)展參數(shù)

? ? 先來看看示例代碼,如下所示:

function sum(){
    let sum=0;
    for (let index = 0; index < arguments.length; index++) {
        sum+=arguments[index];
    }
    return sum;
}
let number=[1,2,3,4,5];
console.log("sum is :",sum(number)); // sum is : 01,2,3,4,5

? ? 以上函數(shù)功能是希望將傳入的參數(shù)進(jìn)行累加處理。如果不使用擴(kuò)展操作符,則需要在傳入函數(shù)前,將參數(shù)進(jìn)行拆分處理,可以使用apply()方法

console.log("sum is :",sum.apply(null,number)); // sum is : 15

? ? 在ECMAScript 6 中,可以通過擴(kuò)展操作符實(shí)現(xiàn)這種操作。對可迭代對象應(yīng)用擴(kuò)展操作符,并將其作為一個參數(shù)傳入,可將可迭代對象拆分,并將迭代返回的每個值單獨(dú)傳入。示例如下所示:

function sum(){
    let sum=0;
    for (let index = 0; index < arguments.length; index++) {
        sum+=arguments[index];
    }
    return sum;
}

let number=[1,2,3,4,5];
// 使用擴(kuò)展操作符
console.log("sum is :",sum(...number));  // sum is : 15

? ? 因?yàn)閿?shù)組的長度已知,所以在使用擴(kuò)展操作符傳參的時候,并不妨礙在其前面或后面再傳其他的值,包括使用擴(kuò)展操作符傳其他參數(shù),示例如下所示:

console.log("sum is :",sum(-10,...number)); // sum is : 5
console.log("sum is :",sum(-10,...number,95)); // sum is : 100
console.log("sum is :",sum(-10,...number,...[1,2,3,4],10)); // sum is : 25

擴(kuò)展參數(shù)操作符其主要作用是將傳入的參數(shù)進(jìn)行拆分為單個元素。

6.7.2 收集參數(shù)

? ? 先來看看示例代碼,如下所示:

function getArray(...numbers){
    return numbers;
}

console.log(getArray(1,2,3)) // [ 1, 2, 3 ]

在定義函數(shù)時,可以使用擴(kuò)展操作符把不同長度的獨(dú)立參數(shù)組合為一個數(shù)組(類似arguments對象的構(gòu)造機(jī)制,收集參數(shù)的結(jié)果會得到一個數(shù)組實(shí)例),

? ? 在使用收集參數(shù)操作符,注意事項(xiàng)如下所示:

  • 收集參數(shù)只能位于命名參數(shù)之后(因?yàn)槭占瘏?shù)的結(jié)果可變,因此僅能做為最后一個參數(shù))
  • 收集參數(shù)前面如果有命令參數(shù),則僅會收集其余的參數(shù)
  • 箭頭函數(shù)支持收集參數(shù)操作符
// 不可以這樣定義
function getArrayA(...value,lastPara){}

// 必須要這樣聲明
function getArrayB(firstPara,...numbers){
    return numbers;
}
// 箭頭函數(shù)支持收集參數(shù)
let getArrayC=(...values) =>{return values;};

console.log(getArrayB()) // []
console.log(getArrayB(1,2,3)) // [ 2, 3 ]
console.log(getArrayB(1,2,3,4,5,6)) // [2, 3, 4, 5, 6]
console.log(getArrayC(1,2,3,4,5,6)) // [1, 2, 3, 4, 5, 6]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容