高级前端
手写代码
【Q031】js 中如何实现 bind

js 中如何实现 bind

更多描述 提供以下测试用例,注意第二条测试用例,因此 bind 可实现 _.partial(func, [partials]) 类似功能

function f(b) {
  console.log(this.a, b);
}
 
//=> 3, 4
f.fakeBind({ a: 3 })(4);
 
//=> 3, 10
f.fakeBind({ a: 3 }, 10)(11);

相关问题:

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 32 (opens in a new tab)

Author 回答者: shfshanyue (opens in a new tab)

最简单的 bind 一行就可以实现,而在实际面试过程中也不会考察你太多的边界条件

Function.prototype.fakeBind = function (obj, ...args) {
  return (...rest) => this.call(obj, ...args, ...rest);
};

测试一下

function f(arg) {
  console.log(this.a, arg);
}
 
// output: 3, 4
f.bind({ a: 3 })(4);
 
// output: 3, 4
f.fakeBind({ a: 3 })(4);

Author 回答者: SageSanyue (opens in a new tab)

那我再抄一个加强版吧嘻嘻 《JavaScript权威指南》P191 ES3实现bind

if (!Function.prototype.bind) {
  Function.prototype.bind = function(o /*, args */) {
    var self = this, boundArgs = arguments;
    return function () {
      var i, args = [];
      for (i = 1; i < boundArgs.length; i++) {
        args.push(boundArgs[i])
      }
      for (i = 0; i < arguments.length; i++) {
        args.push(arguments[i])
     }
     return self.apply(o, args)
    }
  }
}

Author 回答者: Vi-jay (opens in a new tab)

Function.prototype.fakeBind = function (target, ...args) {
  return (...rest) =>
    this.apply(target, args.concat(rest).slice(0, this.length));
};

Author 回答者: hefeng6500 (opens in a new tab)

bind 优化版本:考虑 bind 后返回的函数作为构造函数被 new

Function.prototype.bind = function (context, ...args) {
  const self = this;
  const fn = function (...newArgs) {
    self.apply(this instanceof fn ? this : context, args.concat(newArgs));
  };
 
  fn.prototype = Object.create(this.prototype);
 
  return fn;
};

Author 回答者: zhangtuo1999 (opens in a new tab)

Function.prototype.myBind = function (ctx) {
  ctx ??= globalThis;
  ctx = Object(ctx);
 
  const self = this;
  const args = [...arguments].slice(1);
 
  function bound() {
    self.call(new.target ? this : ctx, ...args);
  }
 
  bound.prototype = self.prototype;
  return bound;
};

Author 回答者: Yinzhuo19970516 (opens in a new tab)

Function.prototype._bind(obj,...args){
  obj.fn = this
  return function(...args){
    const r = obj.fn(...args)
    delete obj.fn
    return  r
  }
}