zoukankan      html  css  js  c++  java
  • 手写系列:call、apply、bind、函数柯里化

    少废话,show my code

    call

    原理都在注释里了

    // 不覆盖原生call方法,起个别名叫myCall,接收this上下文context和参数params
    Function.prototype.myCall = function (context, ...params) {
      // context必须是个对象并且不能为null,默认为window
      const _this = typeof context === "object" ? context || window : window;
      // 为了避免和原有属性冲突,定义一个Symbol类型的属性
      const key = Symbol();
      // call方法的目的是改变函数的this指向,函数的this指向它的调用者,也就是说我们的目标是改变函数的调用者。
      // 下面的this就是函数本身,给_this增加一个名为[key]的方法指向this,就能用_this来调用this了
      _this[key] = this;
      const result = _this[key](...params);
      // 获取函数执行结果后,删除以上添加的属性
      delete _this[key];
      return result;
    };
    

    apply

    和call的区别在于第二个参数

    Function.prototype.myApply = function (context, params) {
      return this.myCall(context, ...params);
    };
    

    bind

    和call的区别在于不立即执行,返回一个函数即可

    Function.prototype.myBind = function (context, ...params) {
      const _this = this;
      // 返回的函数也能接收参数,但是是放在params后面
      return function (...args) {
        return _this.myCall(context, ...[...params, ...args]);
      };
    };
    

    函数柯里化

    函数柯里化,举例,有如下函数

    function test(a, b, c, d, e) {
      console.log(a + b + c + d + e);
    }
    

    有一个curry转换函数对test函数进行一些转换

    function curry(){
      // todo
    }
    const transformTest = curry(test, ...args)
    

    转换之后,原本一次性传过去的参数现在可以分步传参

    // 使得
    test(1,2,3,4,5)
    // 等同于
    transformTest(1)(2)(3)(4)(5)
    // 或者
    transformTest(1, 2)(3)(4, 5)
    // 又或者
    transformTest(1, 2, 3, 4)(5)
    

    curry函数应该怎么写?

    function curry(fn, ...args) {
      // 判断参数个数是不是等于原函数参数个数
      // 如果是,直接返回调用结果
      if ([...args].length >= fn.length) {
        return fn(...args);
      } else {
        // 如果不是,则返回一个函数
        return (...params) => {
          // 将前面传的全部参数传给curry,回到第一步的if判断,直到参数个数满足要求
          return curry(fn, ...args, ...params);
        };
      }
    }
    

    本文GitHub链接:手写系列:call、apply、bind、函数柯里化

  • 相关阅读:
    JS中的原型规则与原型链
    JS中的“==”与强制类型转换
    协作开发中常用的Git命令小结
    JavaScript变量类型检测总结
    IDEA IntelliJ常用设置以及快捷键(转)
    Spring 发送 Email
    SSM框架的整合思路&功能实现
    使用Eclipse把java文件打包成jar 含有第三方jar库的jar包
    基于CDH5.x 下面使用eclipse 操作hive 。使用java通过jdbc连接HIVESERVICE 创建表
    Volley源码学习笔记
  • 原文地址:https://www.cnblogs.com/wangmeijian/p/14219155.html
Copyright © 2011-2022 走看看