2017-06-16 39 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

但我們調用函數立即綁定在相同的作用域後,你看?那麼爲什麼我們不能使用電話呢? –

相關問題