(day 9)JavaScript学习笔记(函数3)

概述

        这是我的学习笔记,记录了JavaScript的学习过程,我是有一些Python基础的,因此在学习的过程中不自觉的把JavaScript的代码跟Python代码做对比,以便加深印象。在写博客的时候我会尽量详尽的记录每个知识点。如果你完全没接触过JavaScript,那么这一系列的学习笔记可能会对你有所帮助。

        今天主要学习函数,主要是箭头函数、闭包、柯里化、自执行函数、回调函数等内容。

1.箭头函数 

        箭头函数提供了一种更简洁、更直观的方式来编写函数,特别是在处理简短的函数逻辑时,相比于传统的函数声明或函数表达式,箭头函数在语法上更加简洁,如下代码示例,是传统函数声明:

//传统函数声明
function add(a,b){
    return a+b;
}

        如下是传统函数表达式

//传统函数表达式
var add2 = function (a, b) {
  return a + b;
};

        上面的函数都是比较简单的,我们可以采用箭头函数,如下代码示意,箭头函数是匿名函数:

//箭头函数
var add3 = (a, b) => {
  return a + b;
};

        上面的代码还可以更加简化,如下:

//箭头函数简化,如果箭头函数有返回值,并且只有一行代码,可省略关键字return
const add4 = (a, b) => a + b;

        注意上面这种简化写法,只有在函数有返回值,并且只有一行代码的情况下才可以省略关键字return和大括号,如果没有返回值,还是要带大括号,如下代码:        

//箭头函数没有返回值不能省略大括号
var greeting = () => {
  console.log("hello world");
};
//调用函数
greeting();//后面加小括号表示调用。

 2.闭包

        闭包是函数里面再定义函数,这样就形成了闭包。内部的函数可以访问外部函数作用域的变量,并且外部函数不暴露内部函数的话,外部无法访问内部函数,只能在函数内部使用,这样就能形成私有的函数,如下代码示例:        

//如下定义一个函数,求两个数的平方和,在函数内定义了一个求平方的函数
function squarSum(a, b) {
  function squar(x) {
    return x * x;
  }
  return squar(a) + squar(b);
}

console.log(squarSum(2, 3));//调用函数

        上面的代码中函数squar是内部的函数,我们是不能调用的,如下代码示例:

console.log(squarSum(2, 3)); //调用外部函数
console.log(squar(5));//访问不到内部函数,提示:Uncaught ReferenceError: squar is not defined

3.高阶函数(Higher-order function)

        在闭包中内部函数可以作为返回值返回出去,这样就形成了高阶函数,也就是返回函数的函数。如下代码示例

function person() {
  let name1 = "小朋"; //在外部函数里定义变量name1
  //在外部函数里定义内部函数getName
  function getName() {
    return name1; //内部函数可以调用外部函数作用域的变量
  }
  return getName; //返回函数getName
}

        下面我们调用一下这个函数:

//调用函数
let getNa = person(); //调用外部函数,得到的应该是person函数返回的getName函数
console.log(getNa);

        上面输出如下内容,可以看到返回的是一个函数,并且把我们定义函数时的注释内容也返回出来了。

ƒ getName() {
    return name1; //内部函数可以调用外部函数作用域的变量
  }

        最后我们再调用一个getNa,如下代码。

console.log(getNa()); //getNa是一个函数,后面加小括号表示调用,输出:小朋

         这样的话,我就相当于给name1设置了只读属性,只能访问它的值,不能修改它的值,从而起到保护作用。

4.柯里化(curry)

        柯里化(Currying)是将一个接受多个参数的函数转换成一系列函数,每个函数都接受一个单一参数,并返回一个新的函数,直到所有参数都被处理并返回最终结果。这种转换使得我们可以分步传递参数给函数,而不是一次性传递所有参数。

        如下代码示例,我们先定义一个普通函数,求三个数的和,我们调用普通函数的时候直接把三个数传入。

//普通函数
function addTreeNums(a, b, c) {
  return a + b + c;
}

console.log(addTreeNums(1, 2, 3));

        上面的函数可以写出柯里化函数,如下代码:

//柯里化函数
function addTreeNumsCurry(a) {
  return function (b) {
    return function (c) {
      return a + b + c;
    };
  };
}

console.log(addTreeNumsCurry(1)(2)(3));//柯里化函数调用方式

        柯里化函数调用的时候是逐一参数传入,每个都是一个参数,直到全部参数传递完毕,如果我们前两个参数是固定的,我们可以把前两个参数出入后形成一个新的函数,如下代码示例:

//如果前两个变量是固定的,可以先把前两个算出来
let fixedTwo = addTreeNumsCurry(1)(2); //把前两个参数传入,算出来形成一个新的函数,赋值给变量fixedTwo
console.log(fixedTwo(10)); //输出:13
console.log(fixedTwo(20)); //输出:23
console.log(fixedTwo(30)); //输出:33

        PS:在Python中是没有内置的柯里化函数,但是我们可以很容易的自己定义柯里化函数,如下代码示例:

# 以下是Python代码
# 定义柯里化函数
def curry(func):  
    def curried(*args, **kwargs):  
        if len(args) + len(kwargs) >= func.__code__.co_argcount:  
            return func(*args, **kwargs)  
        else:  
            return lambda *args2, **kwargs2: curried(*(args + args2), **(kwargs | kwargs2))  
    return curried  
  
# 示例:一个接受三个参数的函数  
def add_three_numbers(a, b, c):  
    return a + b + c  
  
# 柯里化这个函数  
curried_add_three_numbers = curry(add_three_numbers)  
  
# 你可以分步调用这个柯里化函数  
add_two_numbers = curried_add_three_numbers(1)  
add_one_more = add_two_numbers(2)  
result = add_one_more(3)  
print(result)  # 输出:6  
  
# 或者一次性传入所有参数  
result2 = curried_add_three_numbers(1, 2, 3)  
print(result2)  # 输出:6

        Python中也有第三方库,直接调用第三方库可以直接定义柯里化函数,如下代码示例: 

# 以下是Python代码
# 柯里化函数 借助第三方模块
# from toolz import curry # 这两个第三方模块都可以用,代码是一样的
from funcy import curry # 这两个第三方模块都可以用,代码是一样的

@curry #关键字声明下面的函数是柯里化函数
def addTreeNumsCurry(a,b,c):
    return a+b+c

print(addTreeNumsCurry(1)(2)(3))

fixedTwo = addTreeNumsCurry(1)(2)
print(fixedTwo(10))
print(fixedTwo(20))
print(fixedTwo(30))

 5.自执行函数

        自执行函数,函数定义完之后直接调用它自己,外部是无法访问到的,防止被篡改,内部自己形成了作用域,防止和外面的变量命名冲突。如下代码示例:

let num1 = 10; //在函数外定义变量num1

//匿名函数不能做开头,所以圆括号括起来,后面的括号表示调用它自己
(function () {
  var num1 = 20; //在函数内定义变量num1
  console.log(num1);
})(); //增加小括号表示调用它自己 返回结果为 20

console.log(num1); //无法访问函数内的变量,返回的是函数外的变量,返回10

        PS:在Python中没有与它相对应的概念,lambda函数跟它类似,但是功能及用法不一样。

6.回调函数

        回调函数(Callback Function)指的是一个通过函数指针调用的函数。具体来说,回调函数是将函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就称之为回调函数。这句话可能不好理解,我们来看下面代码示例及注释:        

//定义函数request,cd形参是一个函数
function request(cd) {
  console.log("请求数据");
  cd(); //cd后面加上括号表示调用函数,这里也就回调的位置
  console.log("请求结束");
}

//定义函数callback
function callback() {
  console.log("执行回调");
}

//调用函数request,把callback函数作为参数传入
request(callback);
/*
以上代码运行结果:
请求数据
执行回调
请求结束
*/

        上面的代码还可以将callback函数也可以传入参数,代码改写成如下:

//定义函数request2,cd形参是一个函数
function request2(cd) {
  console.log("请求数据");
  cd("成功"); //cd后面加上括号表示调用函数,括号的内容为实参,这里也就回调的位置
  console.log("请求结束");
}

//定义函数callback2
function callback2(result) {
  console.log("执行回调");
  console.log("执行结果是:" + result);
}

//调用函数request2,把callback2函数作为参数传入
request2(callback2);

/*
以上代码运行结果:
请求数据
执行回调
执行结果是:成功
请求结束
 */

        上面的代码也可以写出箭头函数的形式,缺点是不能复用,如下:

//改写成箭头函数,缺点是不能复用
function request3(cd) {
  console.log("请求数据");
  cd("成功");
  console.log("请求结束");
}

request3((result) => {
  console.log("执行回调");
  console.log("执行结果是:" + result);
});

        以上便是今天的学习内容,如果对你有所帮助,请点个赞再走吧。

  • 23
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件 本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件本人博客文章《mybatis框架-学习笔记Day01》的相关代码文件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值