6 函式
6.1 函式定義
? ? 函式可以封裝陳述句,然后在任何地方、任何時間執行,JavaScript中的函式使用function關鍵字宣告,主要由函式名、函式引數和函式體組成,其基本語法和宣告如下所示:
- 方式一:
function functionName(arg0, arg1,...,argN) {
statements
}
- 方式二:
let variable=function(arg0, arg1,...,argN) {
statements
}
- 方式三:
let variable=(arg0, arg1,...,argN) => {
statements
}
- 如果函式無回傳值,則不需要return陳述句,如果有回傳值,則需要return陳述句
- 在碰到return陳述句后,則立即回傳,后續陳述句不再執行
? ? 示例如下所示:
// 無回傳值函式
function hello(name){
console.log("Hello ,",name);
}
// 存在回傳值函式
function sum(number1,number2){
return number1+number2;
}
// 遇到return陳述句,提前回傳
function testReturn(age){
return "test return ";
console.log("age is:",age);
}
// 使用函式運算式定義函式
let diff=function(number1,number2){
return number1-number2
}
// 箭頭函式
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));
輸出結果如下所示:
Hello , Surpass
sum is : 25
test return
diff is: -11
mul is: 126
6.2 箭頭函式
? ? 箭頭函式實體化的函式物件與正式的函式運算式創建的函式物件行為是相同的,任何可以使用函式運算式的地方,都可以使用箭頭函式,需要注意事項如下所示:
- 1、在僅有一個引數時,可以省略括號,以下兩種寫法完全等效:
let absValue1=(x)=>{return Math.abs(x);};
let absValue2=x=>{return Math.abs(x);};
- 2、當沒有引數時,括號不能省略
let getRandomNumber=()=>{return Math.random()*10;};
- 3、多個引數也需要括號
let div=(a,b)=>{
if(b!=0){
return a/b;
}
else{
return Infinity;
}
};
- 4、大括號省略注意事項:
箭頭函式也可以不使用大括號,但這樣會改變函式的行為,使用大括號就說明包含函式體,即可以在一個函式中包含多條陳述句,跟常規函式一樣,如果不使用大括號,則箭頭后面就只能有一行代碼,如一個運算式、賦值操作等,而且,省略大括號會隱式回傳這行代碼的值,
? ? 示例代碼如下所示:
// 以下兩種寫法都有效
let power1=(x)=>{return x**2;};
let power2=x=>x**2;
console.log("power1 is:"+power1(2)+"\npower2 is:"+power2(2));
// 進行賦值操作
let personInfo={};
let setPersonInfoName=(name)=>personInfo.name=name;
setPersonInfoName("Surpass");
console.log("personInfo is:",personInfo);
// 無效寫法
let sum=(number1,number2)=> return number1+number2;
? ? 箭頭函式雖然語法簡潔,但也有很多場合不適用,箭頭函式不能使用arguments、super 和new.target,也不能用作建構式,此外,箭頭函式也沒有prototype屬性
6.3 函式名
? ? 因為函式名就是指向函式的指標,所以它們跟其他包含物件指標的變數具有相同的行為,即一個函式可以有多個名稱,如下所示:
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()的函式,并將sum賦值給refSum,使用不帶括號的函式名會訪問函式指標,并不會執行函式,此時,refSum和sum都指向同一個函式,呼叫refSum()也可以回傳結果,再將sum賦為null之后,就切斷了它與函式之間的關聯,所以refSum()依然可以照常呼叫,
6.4 函式引數
? ? 在JavaScript中,函式不關心傳入的引數個數、資料型別,其函式引數,在內部表現一個陣列,因此函式呼叫時都會接收到一個陣列,函式并不關心陣列中包含什么,
1.定義函式時,宣告有兩個引數,在呼叫時并不一定就需要傳入兩個引數,也可以傳一個,兩個,三個或不傳,解釋器也并不會報錯,
2.在使用function關鍵字定義(非箭頭)函式,可以在函式內部訪問arguments物件,從中獲取傳入的每個引數值
// 使用引數一
function hello_1(name,message){
console.log("call function ",hello_1.name);
return "Hello"+name+message;
}
// 使用引數二: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"));
輸出結果如下所示:
call function hello_1
Hello Surpass Welcome to Shanghai
call function hello_2
input para length is: 2
Hello Surpass Welcome to Shanghai
? ? 在函式中,arguments物件可以跟引數一起使用,如下所示:
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));
輸出結果如下所示:
result is: 1
result is: 3
result is: 6
如果函式是箭頭函式,則傳入的引數不能再使用arguments關鍵字訪問,而只能通過定義的引數名稱來訪問,
6.5 沒有多載
? ? JavaScript不像Java/C#等,存在函式多載功能,因為在JavaScript中函式不一定有函式名稱,引數可以是0個或多個,所以自然就沒有多載功能,如果在JavaScript中定義了兩個同名函式,則后面定義的函式會覆寫前面定義的函式,示例如下所示:
function sum(){
return arguments[0]+28;
}
function sum(){
return arguments[0]+128;
}
let result=sum(100);
console.log("result is:",result) // 228
6.6 引數默認值
? ? 在ECMAScript5.1 及以前,默認引數值為undefined,而在ECMAScript 6 之后,則可以支持顯式定義默認引數了,如下所示:
- 1.給引數傳undefined 相當于沒有傳值,好處是可以利用多個獨立的默認值
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.在使用默認引數時,arguments 物件的值不反映引數的默認值,只反映傳給函式的引數,,修改命名引數也不會影響arguments 物件,它始終以呼叫函式時傳入的值為準
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.默認引數值并不限于原始值或物件型別,也可以使用呼叫函式回傳的值
let name=["Surpass","Kevin","Tina","Jeniffer"];
let city=["Shanghai","Wuhan","Nanjing","Suzhou"];
let nameIndex=0,cityIndex=0;
function getCity(){
// 每次呼叫后遞增
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());
}
輸出結果如下所示:
Hello Surpass,Welcome Shanghai
Hello Kevin,Welcome Wuhan
Hello Tina,Welcome Nanjing
Hello Jeniffer,Welcome Suzhou
函式的默認引數只有在函式被呼叫時才會求值,不會在函式定義時求值
- 4.箭頭函式同樣也可以使用默認引數,但在僅有一個引數時,則不能省略括號
let hello=(name="Surpass")=>{return `Hello ${name}`;}
console.log(hello()); // Hello Surpass
console.log(hello("Kevin")); // Hello Kevin
6.7 引數擴展和收集
? ? ECMAScript 6 新增了擴展運算子,使用它可以非常簡潔地操作和組合集合資料,擴展運算子最有用的場景就是函式定義中的引數串列,既可以用于呼叫函式時傳參,也可以用于定義函式引數,
6.7.1 擴展引數
? ? 先來看看示例代碼,如下所示:
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
? ? 以上函式功能是希望將傳入的引數進行累加處理,如果不使用擴展運算子,則需要在傳入函式前,將引數進行拆分處理,可以使用apply()方法
console.log("sum is :",sum.apply(null,number)); // sum is : 15
? ? 在ECMAScript 6 中,可以通過擴展運算子實作這種操作,對可迭代物件應用擴展運算子,并將其作為一個引數傳入,可將可迭代物件拆分,并將迭代回傳的每個值單獨傳入,示例如下所示:
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 : 15
? ? 因為陣列的長度已知,所以在使用擴展運算子傳參的時候,并不妨礙在其前面或后面再傳其他的值,包括使用擴展運算子傳其他引數,示例如下所示:
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
擴展引數運算子其主要作用是將傳入的引數進行拆分為單個元素,
6.7.2 收集引數
? ? 先來看看示例代碼,如下所示:
function getArray(...numbers){
return numbers;
}
console.log(getArray(1,2,3)) // [ 1, 2, 3 ]
在定義函式時,可以使用擴展運算子把不同長度的獨立引陣列合為一個陣列(類似arguments物件的構造機制,收集引數的結果會得到一個陣列實體),
? ? 在使用收集引數運算子,注意事項如下所示:
- 收集引數只能位于命名引數之后(因為收集引數的結果可變,因此僅能做為最后一個引數)
- 收集引數前面如果有命令引數,則僅會收集其余的引數
- 箭頭函式支持收集引數運算子
// 不可以這樣定義
function getArrayA(...value,lastPara){}
// 必須要這樣宣告
function getArrayB(firstPara,...numbers){
return numbers;
}
// 箭頭函式支持收集引數
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]
原文地址:https://www.jianshu.com/p/07328d8a31f7
本文同步在微信訂閱號上發布,如各位小伙伴們喜歡我的文章,也可以關注我的微信訂閱號:woaitest,或掃描下面的二維碼添加關注:

作者: Surpassme
來源: http://www.jianshu.com/u/28161b7c9995/
http://www.cnblogs.com/surpassme/
宣告:本文著作權歸作者所有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出 原文鏈接 ,否則保留追究法律責任的權利,如有問題,可發送郵件 聯系,讓我們尊重原創者著作權,共同營造良好的IT朋友圈,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/502741.html
標籤:JavaScript
