首先看一段代码:

let obj = {
x: 100
}; function fn(y) {
this.x += y;
console.log(this);
}

现在有一个需求:在1秒后,执行函数fn,并让其this指向obj。

如果写成

setTimeout(fn, 1000);

这么写的话,fn函数中的this是指向window的,而且也没有传递参数。

如果写成

setTimeout(fn(200), 1000);

这么写的话,this指向依然是window,而且相当于立即执行fn函数,并把结果赋给定时器1秒后再执行,这样肯定不行。

如果写成

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

这么写的话,用call或apply虽然改变了this指向,但都是函数立即执行并把返回结果赋给了定时器,依然无法完成需求。

如果写成

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

这么写的话,用一个匿名函数包起来,等到1秒后执行匿名函数里边的代码,这样便可以完成上述需求。

从中我们可以看出,在某一个阶段之后执行某些代码,我们需要预先把this指向、参数等预先准备好,这种预先处理的思想即柯理化思想。

即,柯理化函数的思想:利用闭包的机制,把一些内容事先存储和处理了,等到后期需要的时候拿来用即可。
 

当然,这个需求如果用bind写的话,也能实现
setTimeout(fn.bind(obj,200), 1000);
因为bind不会立即执行函数,而且可以预先存储一些内容,和柯理化函数的思想相似,但问题是bind不兼容IE8及以下,那么为了通用,我们可以自己封装一个bind方法,从而实现这种需求。
 
/*
* bind:预先处理内容
* @params
* func:要执行的函数
* context:需要改变的this指向
* args:给函数传递的参数
* @return
* 返回一个代理函数
*/
function bind(func, context, ...args) {
return function proxy() {
func.call(context, ...args); //call和apply兼容低版本IE
};
}

完成最开始的需求

setTimeout(bind(fn, obj, 200), 1000);

理解了这种思想,有助于我们更好的阅读别人的代码,如redux源码中applyMiddleware.js、combineReducers.js等很多都用到了这种方式或思想,以后更有助于我们自己写一些插件、组件等。

 
 

JS高阶编程技巧--柯理化函数的更多相关文章

  1. JS高阶编程技巧--compose函数

    先看代码: let fn1 = function (x) { return x + 10; }; let fn2 = function (x) { return x * 10; }; let fn3 ...

  2. JS高阶编程技巧--惰性函数

    在vue.react等框架大量应用之前,我们需要使用jQuery或者原生js来操作dom写代码,在用原生js进行事件绑定时,我们可以应用DOM2级绑定事件的方法,即:元素.addEventListen ...

  3. JS高阶函数的理解(函数作为参数传递)

    JS高阶函数的理解 高阶函数是指至少满足下列条件之一的函数. · 函数可以作为参数被传递 · 函数可以作为返回值输出 一个例子,我们想在页面中创建100个div节点,这是一种写法.我们发现并不是所有用 ...

  4. React.js高阶函数的定义与使用

    /* 高阶函数的简单定义与使用 一: 先定义一个普通组件 二: 用function higherOrder(WrappendComponent) { return } 将组件包裹起来,并用export ...

  5. react.js 高阶组件----很简单的实例理解高阶组件思想

    调试代码之前,我设置了两个缓存 分别是username和content 在控制台console设置两个缓存代码 localStorage.setItem('username','老王')localSt ...

  6. js高阶函数应用—函数柯里化和反柯里化

    在Lambda演算(一套数理逻辑的形式系统,具体我也没深入研究过)中有个小技巧:假如一个函数只能收一个参数,那么这个函数怎么实现加法呢,因为高阶函数是可以当参数传递和返回值的,所以问题就简化为:写一个 ...

  7. JS高阶函数与函数柯里化

    高阶函数 满足下列条件之一的函数: 函数作为参数被传递(如回调函数): 函数可以作为返回值输出: 一些内置高阶函数的例子: Array.prototype.map map()方法通过调用对输入数组中的 ...

  8. js 高阶函数 闭包

    摘自  https://www.cnblogs.com/bobodeboke/p/5594647.html 建议结合另外一篇关于闭包的文章一起阅读:http://www.cnblogs.com/bob ...

  9. js高阶函数

    我是一个对js还不是很精通的选手: 关于高阶函数详细的解释 一个高阶函数需要满足的条件(任选其一即可) 1:函数可以作为参数被传递 2:函数可以作为返回值输出 吧函数作为参数传递,这代表我们可以抽离一 ...

随机推荐

  1. Git详解之文件状态

    前言 其实文件状态根据不同场景有不同的描述,例如:已跟踪.未跟踪.已暂存.已修改.未修改等等,乱七八糟的,今天个人根据自己的使用经验对其进行分类,如有不同建议或者更好的想法也可以留言评论,万分感谢! ...

  2. SpringBoot 的不同

    这些在写前端页面的时候,ssm框架中,在页面做出修改之后,保存一下,重新刷新一下浏览器页面就发生了更新 但是sprigBoot中好像不一样,好像是需要对页面进行重新编译一下,浏览器页面才会发生变化 ( ...

  3. spring @Scheduled注解 定时任务 详解

    scheduled的使用注解的方式进行调度 先要配置spring.xml xmlns:task="http://www.springframework.org/schema/task&quo ...

  4. Android Studio中Gradle sync failed

    问题:Android Studio中更新同步Gradle 失败 Gradle sync failed: Could not find com.android.tools.build:gradle:3. ...

  5. Java 程序是如何执行的

    Java 程序是如何执行的 了解任何一门语言的精髓都是先俯览其全貌,从宏观的视角把握全局,然后再深入每个知识点逐个击破,这样就可以深入而快速的掌握一项技能.同样学习 Java 也是如此,本节就让我们先 ...

  6. CentOS 7 上CNVnator安装

    1.到github上下载最新版本 https://github.com/abyzovlab/CNVnator/releases 2.先看INSTALL文件,要求以下依赖,我的机器上已经安装了前两个,所 ...

  7. 13、FrameRely

    Frame Relay 美国国家标准化协会(American National Standard Institute,简称ANSI)国际电信联盟远程通信标准化组 ITU-T 1.是由ITU和ANSI制 ...

  8. js笔记(3)--js实现数组转置(两种方法)

      js实现数组转置   第一种方法:   <script>     window.onload=function(){     var array1=[[11,22,33,333],[4 ...

  9. NetworkX包

    官方教程 NetworkX是一个创建,操作,研究复杂网络的结构,动态,功能的python包. #创建一个network import networkx as nx G = nx.Graph() #no ...

  10. Altium Designer 14安装破解

    Altium Designer 14简称AD14,是一款专业的PCB设计软件,利用他可以计出专业的PCB元件.Altium Designer 14.3.10是目前的最新版本. Altium Desig ...