有关javascript回调的详细信息

时间:2017-11-17 17:41:39

标签: javascript

我对某些事情感到好奇,想象一下关闭窗口的链接。请参阅下面的代码,并阅读评论:

var a = document.querySelector('a');

//
// Since a.onclick requires a callback I have the following code:
//

a.onclick = function() { window.close() }; // This works fine.
a.onclick = function() { close() }; // This works as well.
a.onclick = () => { close() }; // This also work.
a.onclick = () => close(); // This works.

// But...

a.onclick = window.close; // This doesn't work.
a.onclick = close; // Neither this.

// But, why not?? Since onclick requires a function, and window.close is a 
// function and close is just the shorten way to call window.close?

// However...

a.onclick = close.bind(); // This works fine....

所以研究员们,因为onclick收到了一个函数,为什么要设置" close"不做这个工作?它应该"注册"函数关闭(window.close)作为"回调"对于该动作,并在事件被触发时调用它(如close.call());

我真的不明白这种行为

2 个答案:

答案 0 :(得分:4)

这有点棘手。

我们习惯于看到window持有我们忘记window本身就是一个对象的所有全局变量。这是对的 - 它是代表浏览器窗口的对象。

close不仅仅是一个函数,而是window对象的一种方法(参见:https://developer.mozilla.org/en-US/docs/Web/API/Window/close)。

因此,当您将close转换为函数引用时,它会失去与this的绑定(应该指向window)。

其他人通过偶然事件工作:

  1. a.onclick = function() { window.close() };

    这很明显。您直接调用该方法,以便获得正确的this

  2. a.onclick = function() { close() };

    如果处于严格模式,那么不属于任何对象的函数将指向全局对象(window)或undefined。因此,当不在严格模式下时,这将起作用。

  3. a.onclick = () => { close() };

    与第2号相同的解释。

  4. a.onclick = () => close();

    与3相同的解释,但未使用可选的{}

  5. 注意:有人可能会认为2,3和4是不同的机制,但箭头功能会影响this的行为方式,而不会调用this.close()。因此,只有this中的close值很重要。箭头功能不会改变它。

    请注意,当不在严格模式下时,以下内容也应该有效:

    a.onclick = () => { this.close() }
    

    我认为从我之前的解释中可以看出为什么上述情况应该有效。

答案 1 :(得分:2)

所有关于方法与其this的绑定。如果您对某个方法有Function引用,那么请对其进行调用,它不会知道"知道"该方法所属的对象(this将不再是Window),因此如果.close()需要了解其窗口对象,则函数调用将失败。

bind通过将this修复为特定对象来解决此问题:

a.onclick = window.close.bind(window);