函数
JavaScript中提供函数的定义和调用方式
1,基本语法
return x + y;
}
const sum = add(1,2);
console.log(sum);//结果为3
2,参数默认值
function add(x = 1,y = 2){
return x+y;
}
const sum1 = add();
console.log(sum1);//结果为3
const sum2 = add(2);
console.log(sum2);//结果为4
const sum3 = add(2,3);
console.log(sum3);//结果为5
3,箭头函数
ES6增加箭头函数特性
(x,y)=>{
return x + y;
}
箭头函数没有函数名,只描述了参数列表和函数体。
通常情况下,箭头函数一般作为值进行传递。
const aFunc = ()=>{
console.log('xxx');
}//将箭头函数赋值给aFunc变量
const bFunc = aFunc;//通过aFunc变量为bFunc变量赋值
箭头函数无法直接被调用,只能借助存放箭头函数值的变量进行调用,调用方法与调用普通函数一样
const add = (x,y)=>{
return x+y;
}
const sum = add(1,2);
console.log(sum);//结果为3
箭头函数也经常作为函数的参数,为函数形参赋值
function Test(func){
func();
}
const f1 = ()=>{
console.log('a');
}
const f2 = ()=>{
console.log('b');
}
Test(f1);//输出结果为a
Test(f2);//输出结果为b
4,高阶函数
高阶函数本质为能够接收其他函数作为参数传入的函数。也就是说,高阶函数本身也是一种函数,只不过它的参数可以为其他函数,一般我们用箭头函数作为高阶函数的参数。
例如我们上文中提到的Test()函数,可以称为一个高阶函数。
我们对高阶函数的要求为,会使用,不要求会编写。这是基于我们当前开发技术提出的要求。在ReactNative开发中,我们会遇到很多写好的高阶函数,供我们使用,来完成更复杂的功能。但我们并不需要自己编写一个高阶函数。
所以本节重点是研究如何使用高阶函数。
首先我们需要先明确一个概念:函数的类型。
函数类型由其输入参数和返回值决定,输入和返回值相同的函数,我们称之为同一类型函数。例如:
(x,y)=>{
return x+y;
}
(a,b)=>{
return a-b;
}
这两个为同类型函数,因输入参数和返回值类型相同。
我们来看第一个例子,首先我给出一个写好的高阶函数,同学们不用纠结高阶函数如何实现。
//func1的参数是一个f,f的类型为无输入参数,无返回值。
//func1为一个高阶函数
function func1(f){
f();
}
有了func1这个高阶函数,所有无输入参数,无返回值的函数,都可以作为参数出入该高阶函数。例如:
f1 = ()=>{
console.log('hello');
}
func1(f1);//输出hello
读到这里,大家可能会有一个疑问。使用了高阶函数,执行操作也仅仅是打印一个hello字符串。这样做的意义是什么。接下来我们便进行讨论,解释高阶函数的意义。
5,高阶函数的意义
在讨论这个问题之前,我们先明确两个概念,在上文中提到的,
func1:我们称之为高阶函数。
f1:是高阶函数的参数,也是一个函数。我们一般称之为这个函数为功能函数
高阶函数+功能函数的组合,才能实现完整的功能。其中高阶函数一般为框架提供,功能函数一般由使用框架的开发者自己编写。
为什么要是这样的组合呢?
是因为,我们做应用开发,尤其是App开发,如果代码从零开始写,那成本是非常高的。所以,我们在开发的时候,都是在各种框架下进行二次开发,这样可以非常有效的提升开发效率,避免大量重复基础的工作。我们可以认为,如果一个App的开发工作是100,那么一个优秀的框架可以帮助我们完成其中的70-80的工作量。我们只需要完成20-30的工作量便可开发一个App并发布。
所以,开发效率的核心是框架。
那框架是如何被开发出来的呢?
这个问题比较复杂,在此我们举一个简单的例子,方便大家理解,并不做深入探讨。
比如我们书中提供一个计算框架共大家使用。
计算这个功能不止包含法则,还包含数据的存储和验证。我们平时写的1+2,仅仅是通过运算符对计算法则的描述。
function compute(x,y,f){
return f(x,y);
}
上面代码中的compute便是我给大家的一个计算框架,我们可以想计算框架中传入两个计算变量一个计算规则,计算规则通过函数来描述。
我们先用计算框架做一个简单的加法计算:
//准备计算数据
const p = 1;
const q = 2;
//先用函数描述一个加法计算规则
const f1 = (a,b)=>{
return a+b;
}
//调用计算框架进行计算
const sum = compute(p,q,f1);
console.log(sum);//打印结果为3
计算框架使用我们传入的计算数据和计算法则,计算出我们的结果。这个计算框架就是高阶函数。
到这里,大家可能还是不能够理解,我简单的a+b也能完成这样的操作,为什么要用计算框架这个高阶函数。这是因为,我们的问题不足够复杂,没法提现计算框架的优势。下面我们在构造一个更复杂的计算。
我们规定,计算法则为:两个输入参数之和如果为奇数就相乘,如果之和为偶数结果为0。
这样稍微复杂的计算规则,普通的处理方式就没法进行了,这时候就体现出计算框架的功能了。
//构造计算规则
const f2 = (x,y)=>{
const s = x+y;
if(s%2 == 0){
return 0;
}
return x*y;
}
const result1 = compute(2,2,f2);
console.log(result1);//结果为0;
const result2 = compute(1,2,f2);
console.log(result2);//结果为2
通过计算框架,我们不需要关系具体计算过程,我们只需要描述特定的业务即可。
这便是高阶函数的意义:提供了一种使用框架的方法,让我们开发更加高效。
6,高阶函数的应用
这一节我们举两个例子,说明高阶函数的使用场景
- 提供操作基础
- 提供事件回调
一般来说,高阶函数无法独自使用,必须配合我们写的功能函数才能起作用。
案例1,数组的遍历
//一般我们使用for循环进行数组的遍历
const array = [1,2,3,4];
for(let i = 0; i < array.length; i++){
const value = array[i];
console.log(value);
}
此种方式,我们需要手写一个for循环来进行,但是大家思考一下,所有的数组遍历模式都差不多,那么有没有框架将for循环这种重复的基础操作封装,只让我们写遍历规则呢。
答案是肯定的,JavaScript语言本身的Array对象中,包含了一个map()方法,该方法便是一个高阶函数,其参数需要传入一个函数,函数类型为:两个输入参数,一个返回值。
第一个输入参数为数组中某一个元素的值
第二个输入参数为该元素在数组中的索引
map方法会用返回值组成一个新的数组并返回
const array = [1,2,3,4];
array.map((value,index)=>{
console.log(value);
})//依次打印数组中每一个值
const arr1 = [1,2,3,4];
const arr2 = arr1.map((value,index)=>{
return value * 2;
});
console.log(arr2);//结果为[2,4,6,8];
通过使用框架提供的高阶函数map,我们无需关注如果遍历数组,只需要关注遍历规则即可。
案例2,Timer事件回调
Timer是JavaScript中定时器,可以进行周期性操作,例如每隔1秒钟打印一个字符串。实现这样周期性操作,同样使用的高阶函数
//setInterval(func,msecond)
//该函数有两个输入参数,第一个输入参数为一个函数,类型为无输入参数,无返回值。第二个输入参数为间隔时间,单位毫秒
//我们通过函数描述周期性需要完成的任务,例如是一个打印任务
const task = ()=>{
console.log('hello');
};
//只需要将此任务传入高阶函数,并设置好间隔时间,该任务便会安装计划运行,
setInterval(task,1000);//每1秒钟打印一个hello
高阶函数的应用场景很多,我们经常用的就是以上两种类型。
对于高阶函数,是区分程序员能力的标杆,后续的案例,我们会接触越来越多的高阶函数。使大家对高阶函数的引用有更加深刻的认识。