为什么在调用和应用不绑定工作时?

Why bind work's when call and apply doesn't?

我现在正在编写自己的js库,我对这段代码有点困惑:

var par = document.querySelector('#par');

Element.prototype.fadeIn = function() {
  this.style.opacity = 0;
 var that = this;
  
  var last = +new Date();
  var tick = function() {
   console.log(this);
    this.style.opacity = +this.style.opacity + (new Date() - last) / 400;
    last = +new Date();

    if (+this.style.opacity < 1) {
      (window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);
    }
  };
  tick = tick.bind(that);
 tick();
};

par.fadeIn();
<p id="par">123</p>

此代码工作正常,但如果我们使用 tick.apply(that) 而不是绑定 - 它不起作用!有人可以解释一下为什么吗?

bindapply(或 call 就此而言)的工作方式并不完全相同。

  • apply 将函数绑定到给定的 this 并立即调用它;
  • 另一方面,
  • bind 创建一个绑定到给定 this 的新函数,但不要调用它。

所以这两个是等价的:

myFunction.call(that)

// and

myFunction.bind(that)() // <- see the extra parenthesis here 

因此,在您的情况下,您可以执行以下任一操作:

tick = tick.bind(that)
tick()

// OR

tick.call(that) // no need for extra assignment, the function is called right away

你还有一个问题。事实上,当您执行 tick = tick.bind(this) 时,您会覆盖刚刚在上面定义的 tick 函数......并且 requestAnimationFrame(tick) 能够工作 因为 tick 现在绑定到 this.

当您使用 call 时,tick 不会被修改,当 requestAnimationFrame 触发时,tick 函数不会被绑定。

这是我的建议:

var tick = function () {
  //...
}.bind(that) // now tick is created and instantaneously bound to the correct `this`

tick() // first call

.bind "binds" 返回函数的上下文,供以后使用,而 .apply.call 使用给定的上下文调用函数。