函数

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

高阶函数的应用场景很多,我们经常用的就是以上两种类型。

对于高阶函数,是区分程序员能力的标杆,后续的案例,我们会接触越来越多的高阶函数。使大家对高阶函数的引用有更加深刻的认识。

results matching ""

    No results matching ""