高级前端js【Q032】js 中什么是 softbind,如何实现

js 中什么是 softbind,如何实现

更多描述 相关问题:

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 33

Author 回答者: newwangyiyang

bind函数多次调用会已第一次绑定的this为准,softbind已最后一次绑定传入的this为准;

Author 回答者: miaooow

  Function.prototype.softBind = function(obj, ...rest) {
    const fn = this
    const bound = function(...args) {
      const o = !this || this === (window || global) ? obj : this
      return fn.apply(o, [...rest, ...args])
    }

    bound.prototype = Object.create(fn.prototype)
    return bound
  }

function foo() { console.log(name: ${this.name}); }

let obj = {name: "obj"};
obj2 = {name: "obj2"};
obj3 = {name: "obj3"};

let fooBJ = foo.softBind(obj);
fooBJ();  // name: obj   这个时候软绑定已经生效了,this绑定到obj上
obj2.foo = foo.softBind(obj);
obj2.foo(); //name: obj2   这里已经的this隐式绑定到obj2上了
fooBJ.call(obj3); // name: obj3  这里this被硬绑定到obj3上了
setTimeout(obj2.foo, 100); // name: obj  软绑定了最初的obj

Author 回答者: shfshanyue

TODO

Author 回答者: shuangcherry

bound.prototype = Object.create(fn.prototype); 为什么要有这一句,不是很懂

Author 回答者: shen076

Function.prototype.softBind = function (obj, ...args) {
  const fn = this;
  return function (...args2) {
    return fn.apply(this === global ? obj : this, args.concat(args2));
  };
};

Author 回答者: zhangtuo1999

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

Author 回答者: rujptw

bound.prototype = Object.create(fn.prototype); 为什么要有这一句,不是很懂 是要考虑到new的情况来着

Author 回答者: Yeti-xxx

实现一个Bind:

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

const yeti = {
    name: 'yeti'
}

// 实现一个bind
Function.prototype.newmyBind = function (obj, ...args) {
    const that = this
    return function (...rest) {  //返回一个修改好this的函数
        // ...rest来自返回函数传入的参数  ...args是调用Bind时传入的参数
        that.call(obj, ...args, ...rest)
    }

}

const resBind = person.newmyBind(yeti, 1, 2, 6) //1 2 6 就是...args
resBind(5, 6)   //传入...rest

Author 回答者: Maystar777

软绑定:首先检查调用时的this,如果this绑定到全局对象或者undefined,那就把this绑定到入参obj,否则不会修改this。

也就是this软绑定到obj上,永远有一个obj来兜底,它优先级小于隐式绑定(a.foo)、显式绑定(call/apply)和new绑定,但是高于默认绑定(独立函数调用)。