zoukankan      html  css  js  c++  java
  • JS高阶编程技巧--柯理化函数

    首先看一段代码:

    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等很多都用到了这种方式或思想,以后更有助于我们自己写一些插件、组件等。

     
     
  • 相关阅读:
    平分糖果——BZOJ 1045
    浙大月赛——ZOJ Problem Set 3574
    jsp 自定义标签的写法
    C#扩展方法(转贴)
    window mobile 防止系统休眠代码
    jbpm sql使用动态参数方法
    spring 多数据源配置实现
    原创jquery蒙版控件
    jbpm 错误解决方法
    cas server 配置
  • 原文地址:https://www.cnblogs.com/ronaldo9ph/p/12303333.html
Copyright © 2011-2022 走看看