覆盖``this`在.bind and apply''中



我正在阅读此页面只是为了刷新.apply语法,我意识到我的JS知识有差距:

您可以使用.bind.apply在函数中更改this的值(我假设.call遵循与.apply相同的规则,因此我不会单独谈论它(。所以我想知道,如果我使用.bind,然后用.apply调用它,这将优先?

所以我只是从W3Schools中示了一个示例,然后对其进行了修改:

var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}
var person1 = {
  firstName: "John",
  lastName: "Doe"
}
var person2 = {
  firstName: "Mary",
  lastName: "Anne"
}
fn = person.fullName.bind(person2);
console.log(fn.apply(person1, ["Oslo", "Norway"]));

因此,如果它打印了玛丽·安妮(Mary Anne(,.bind给出的this的值优先于.apply给出的值。

这样做了!嫁给安妮印刷。因此,这让我想知道我不太了解的有关this是否还有其他规则。例如,致电.bind后可以重新启动?

.bind返回a 绑定函数 BOND BOND函数箭头函数将永远不会再改变其上下文,因此您无法重新 .bind.apply另一个上下文。

如果我们假设.bind会以JavaScript本身写作可能会更加清楚...然后将其写成:

  function bind(context, ...args) {
    const fn = this;
    return function(...args2) {
      // Note: "this" does not get accessed inside this function, so .bind ing it or .apply ing another context doesnt change anything
      return fn.call(context, ...args, ...args2);
    }
 }

按规范:

注2:如果func是箭头函数或绑定函数,那么步骤x。

中的函数[[call]]将忽略thisarg

这适用于所有三个绑定函数。

bind创建一个不是正常函数的绑定函数(它是一个异国对象(,不包含原型。

https://www.ecma-international.org/ecma-262/6.0/#sec-function.protype.protype.apply

除了实现Function.prototype.bind的方式外,没有什么可以阻止重新绑定的。而且,您是对的,一旦打电话绑定this值是固定的,而Function.prototype.apply不能覆盖它。

而不是使用Function.prototype.bind,您可以使用它来绑定参数:

Function.prototype.create = function(){
  const args = arguments;
  const original = this;
  return function() {
    return original.call(this, ...args, ...arguments);
  }
};

但是,修改原型可能是有问题的,因此我会避免并创建一个辅助功能。我确定像Lodash这样的公用事业库可以做到这一点,或Ramda。

您可以这样使用:

const fn = function (one, two, three) {
    return this + one + two + three;
};

const boundfn = fn.create(1, 2);
const val = boundfn.call(-6, 3);
console.log({val});

是的,我们将-6作为this的值传递。:(

-6 + 6 = 0

注意:避免这样做!使用上下文是错误的方法,绝对不起作用。我会避免将this传递到周围

.bind使用添加的this上下文创建一个新功能,以及您想要的任何参数 curry ,并且不可能用applycall(除非您的bind方法不是本地的(答案已经有一个https://stackoverflow.com/a/31656748/906265,它提到了bind的ES2015规格

来自mdn

bind((方法创建了一个新函数,当调用时,该函数将其此关键字设置为提供的值,并在称为新函数时提供的一个给定参数序列。

.apply.call允许您在调用函数时覆盖 this CC_35函数的值,但对于ES2015规格注释2

中编写的箭头或绑定函数不起作用

如果func是箭头函数或绑定函数,则该函数将忽略

最新更新