- A+
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,或扫描下面的二维码添加关注: