2017-06-16 40 views
0

现在我写我自己的JS库和我有点混淆了这个写代码:为什么绑定工作的时候通话和应用不?

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

 
Element.prototype.fadeIn = function() { 
 
    this.style.opacity = 0; 
 
\t var that = this; 
 
    
 
    var last = +new Date(); 
 
    var tick = function() { 
 
    \t 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); 
 
\t tick(); 
 
}; 
 

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

此代码工作的很好,但如果我们tick.apply(即)而不是绑定 - 它不起作用!有人可以解释我为什么吗?

+3

因为'bind'和'apply'做了完全不同的事情!? 'bind'只是将上下文绑定到一个函数,而'apply' ***立即用上下文调用该函数。 – deceze

+0

我认为有必要说,适用,需要两个参数,第一个参数是范围或上下文,第二个参数是与参数 – Raulucco

+0

这是不适用于调用。如果我们没有参数 - 我们不需要申请或致电 –

回答

1

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

当您使用呼叫时,tick未被修改,并且当​​触发时,tick功能未被绑定。

这里是我的建议:

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

tick() // first call 
+0

我知道这个规则,但在这个例子中我们调用了函数tick()紧接在绑定之后,所以它应该是相当于tick.call(this); –

+0

@Pavlo然后,当你使用'apply' /'call'时,你需要定义什么“不起作用”。 – deceze

+0

https://jsfiddle.net/chebotiuk/2k8jvasg/ 未捕获TypeError:无法读取undefined属性'opacity' –

0

.bind“结合”的背景下返回的功能,以备后用,而.apply.call调用与给定上下文的功能。

+0

但我们调用函数立即绑定在相同的作用域后,你看?那么为什么我们不能使用电话呢? –

相关问题