san.js源码解读之工具(util)篇——bind函数兼容

一、源码解析

/**
 * Function.prototype.bind 方法的兼容性封装
 *
 * @param {Function} func 要bind的函数
 * @param {Object} thisArg this指向对象
 * @param {...*} args 预设的初始参数
 * @return {Function}
 */
function bind(func, thisArg) {
    var nativeBind = Function.prototype.bind; // 1
    var slice = Array.prototype.slice; // 1
    // #[begin] allua
    if (nativeBind && func.bind === nativeBind) { // 2
    // #[end]
        return nativeBind.apply(func, slice.call(arguments, 1));
    // #[begin] allua
    }

    /* istanbul ignore next */
    var args = slice.call(arguments, 2); // 3
    /* istanbul ignore next */
    return function () { // 4
        return func.apply(thisArg, args.concat(slice.call(arguments)));
    };
    // #[end]
}
  1. 获取 bind 和 slice 原函数

    var nativeBind = Function.prototype.bind;
    var slice = Array.prototype.slice;
    
  2. 判断原 bind 函数是否存在并且和传入函数原型链上的 bind 函数是否相同,如果相同就直接调用原 bind 函数

        return nativeBind.apply(func, slice.call(arguments, 1)); // 返回 bound 函数
    

    这里需要注意的是 bind 需要使用 apply 函数进行调用。因为 bind 必须在函数上调用,如果 nativeBind(func, slice.call(arguments, 1)) 这么传入会报错。

  3. 如果环境中没有 bind 函数,则需要兼容 bind 函数,兼容 bind 函数原理和手写 bind 函数基本一致。

    
    var args = slice.call(arguments, 2); // 获取当前函数下标从2开始(包含2)的参数
     return function () { // 返回一个匿名函数(类似 bound)
         return func.apply(thisArg, args.concat(slice.call(arguments))); // 拼接函数参数
     };
    

二、示例

function khDemo(c) {
      return this.a + this.b + c;
  }
  let obj = {
      a: 1,
      b: 2
  }
  let bound = bind(khDemo, obj);
  console.log(bound(3));

san.js源码解读之工具(util)篇——bind函数兼容_第1张图片

你可能感兴趣的:(san.js,javascript,开发语言,ecmascript,san.js)