秒懂高阶编程之函数绑定及柯理化函数思想

简介: 秒懂高阶编程之函数绑定及柯理化函数思想

在介绍柯理化函数思想之前我先讲一个定义,叫函数绑定。

所谓函数绑定,就是要创建一个函数,可以在特定的this环境中以指定参数调用另一个函数。通常和回调函数与事件处理程序一起使用。通俗来说就是改变this指向。

柯理化函数的思想:
柯理化函数简单的说就是一个大函数返回一个小函数,原理就是利用闭包的机制,把一些内容实现存储和处理了,等到后期需要的时候拿来即用即可 。
举个例子,假如有一个div, div有过一个事件,点击想要执行相应操作。代码如下:

<div class="box" id="box">这是一个盒子</div>
<script>
  let obj = {
      x: 100
  }
 function fn (y) {
    console.log(y);
    this.x += y;
    console.log(this);
 }
 box.onclick = fn.call(obj, 200);
</script>

柯理化函数1.gif

如上代码,我们想点击box,然后事件会触发,最后打印this。先不考虑别点,我们这么写的想法是想让,this的指向是obj,但是实际的结果却不是,看到控制台打印的结果是box这个元素。
对于这种情况,我们首先想到的就是改变this指向,利用bind,如下:

<div class="box" id="box">这是一个盒子</div>
<script>
  let obj = {
      x: 100
  }
 function fn (y) {
    console.log(y);
    this.x += y;
    console.log(this);
 }
 box.onclick = fn.bind(obj);
</script>

柯理化函数2.gif

这回我们再看一下输出。这回便是我们想要的。但此时没有传参,所有y是MouseEvent,所以传参的话结果如下:

<div class="box" id="box">这是一个盒子</div>
<script>
  let obj = {
      x: 100
  }
 function fn (y) {
    console.log(y);
    this.x += y;
    console.log(this);
 }
 box.onclick = fn.bind(obj,200);
</script>

柯理化函数3.gif

但是有一个问题,这个问题就是bind不兼容IE6/7/8,由此我们能想到的是applycall,但它们两个都是将函数改变this指向,并立即执行。
由这个特点。我们不能直接将函数写成如下形式:

<div class="box" id="box">这是一个盒子</div>
<script>
  let obj = {
      x: 100
  }
 function fn (y) {
    console.log(y);
    this.x += y;
    console.log(this);
 }
 box.onclick = fn.call(obj, 200);
</script>

柯理化函数4.gif

这样写的结果,函数被立即执行。这显然不是我们想要的结果。
我们改动一下:

<div class="box" id="box">这是一个盒子</div>
<script>
  let obj = {
      x: 100
  }
 function fn (y) {
    console.log(y);
    this.x += y;
    console.log(this);
 }
 box.onclick = function () {
  fn.call(obj, 200);
}
</script>

柯理化函数5.gif

这样的结果我们再来看看。没错,这样依旧符合我们想要的结果。
这个过程我们做了什么呢,我们将点击事件绑定一个匿名函数,这个匿名函数里将函数的this执行改变并执行。这里的实际上是预先处理this,预先传递一些参数,整个操作是让函数在某些情况下才去执行,而不是立即执行。相当于把一些内容或者事情提前处理了,等到需要的时候在拿来用。这也是利用了闭包的保存机制,这个过程就是函数柯理化的思想。
再举另一个例子理解一下。假如一个定时器想要执行1s后执行fn这个方法。

<div class="box" id="box">这是一个盒子</div>
    <script>
        let obj = {
            x: 100
        }
        function fn (y) {
            console.log(y)
            this.x += y;
            console.log(this);
        }
        setTimeout(fn, 1000);
    </script>

柯理化函数6.gif

上面的写法没办法传参,况且this也不是我们想要的。
改成:

 setTimeout(fn(200), 1000);

柯理化函数7.gif

这样虽然传参了,但this依旧不是我们想指向的obj,同时此时是相当于在立即将fn的结果输出而已。如果传参再改变this指向改成一下:

setTimeout(fn.call(obj,200), 1000);

柯理化函数8.gif

这样的结果就是函数会立即执行了,并不是想要的在1s后执行fn函数。
按照上面的思想,思路我们可以改成:

setTimeout(function(){fn.call(obj,200)}, 1000);

柯理化函数9.gif

这样的结果就是1s后执行匿名函数,再执行的同时会将fn执行。
以上的讲解不知你是否对柯理化编程思想时候有一些些的理解。希望对你有所帮助。

相关文章
|
3月前
|
Python
Python函数式编程:你真的懂了吗?理解核心概念,实践高阶技巧,这篇文章带你一次搞定!
【8月更文挑战第6天】本文介绍了Python中的函数式编程,探讨了高阶函数、纯函数、匿名函数、不可变数据结构及递归等核心概念。通过具体示例展示了如何利用`map()`和`filter()`等内置函数处理数据,解释了纯函数的一致性和可预测性特点,并演示了使用`lambda`创建简短函数的方法。此外,文章还强调了使用不可变数据结构的重要性,并通过递归函数实例说明了递归的基本原理。掌握这些技巧有助于编写更清晰、模块化的代码。
38 3
|
4月前
|
编译器 程序员 C++
【C++高阶】掌握C++多态:探索代码的动态之美
【C++高阶】掌握C++多态:探索代码的动态之美
44 0
|
C语言
C数组超细节精髓
C数组超细节精髓
82 0
|
6月前
|
并行计算 数据处理 开发者
Python函数式编程:探索优雅的编程范式
传统的编程范式中,命令式编程和面向对象编程占据主导地位。然而,Python函数式编程作为一种新颖而强大的范式,通过引入函数作为一等公民和不可变性等特性,为开发者提供了更加优雅和灵活的编码方式。本文将深入探讨Python函数式编程的概念与应用,包括高阶函数、纯函数、惰性计算以及函数式编程在并行处理和数据处理方面的实际应用。
|
6月前
|
Serverless 开发者 Python
Python编程中的函数式编程思想探究
【2月更文挑战第10天】传统的程序设计是以过程为中心,而函数式编程则将函数视为基本构建块,强调函数的纯洁性和不变性。本文将从Python编程语言的角度探讨函数式编程思想在实践中的应用,介绍函数式编程的概念、特点以及在Python中的具体实现方式,帮助读者更好地理解和运用函数式编程范式。
40 0
|
6月前
|
Serverless 开发者 Python
Python函数式编程:从概念到应用的完整指南
在 Python 中,函数式编程是一种流行且强大的编程范式,它不仅可以使代码更加简洁、优雅,而且还能提高程序的可读性和可维护性。本文将从基础概念入手,详细讲解 Python 函数式编程的核心思想、常用函数和实际应用。无论你是 Python 新手还是经验丰富的开发者,本文都能为你提供全面的参考和指导。
|
6月前
|
Serverless 对象存储 C++
第十三章:C++面向对象编程思想详解
第十三章:C++面向对象编程思想详解
121 0
|
前端开发 JavaScript 算法
解密二叉树:探索概念、类型与常见算法的奥秘(顺带说一下React中的reconcile)
二叉树作为程序的一种数据结构,应用广泛,比如React中的reconcile过程,Fiber树的调和过程。确实,在React中,Fiber树是通过child和sibling连接子节点和兄弟节点的方式来表示的,这与普通的二叉树有所不同。 在React中,reconcile过程是将虚拟DOM转化为实际DOM的过程。通过比较新旧两棵树的差异,React可以高效地更新实际DOM,而不是每次都完全重新渲染整个DOM树。这个过程中会涉及到对Fiber树的遍历和调整,确保更新只发生在需要更新的部分。 Fiber树作为一种数据结构,可以帮助React跟踪组件的状态和变化,以及进行调度和渲染。它使用链表的形
57 1
解密二叉树:探索概念、类型与常见算法的奥秘(顺带说一下React中的reconcile)
|
存储 安全 Java
Java面向对象编程三大特征 - 封装
Java面向对象编程三大特征 - 封装
78 0
|
人工智能 算法 安全
8种提升程序猿编程能力的方法+编程思维四个核心:分解、抽象、模式识别和算法
对于程序员来说,提高自己的编程能力,算是给自己定的职业发展目标之一,不过定一个成为编程大神的目标很容易,具体做起来可能就不是一件简单的事了。首先,既然决定“我要变得更好”,得先知道“更好”是什么样子的。另外,不能“想变得更好”,却没有任何具体可行的措施。
922 2
8种提升程序猿编程能力的方法+编程思维四个核心:分解、抽象、模式识别和算法
下一篇
无影云桌面