HTML属性中事件处理程序中的“ this”

Ant*_*arf 0 javascript this handler

我以为我会理解“ this”关键字,直到看到以下代码:

<body>
    <button onclick="go()">clic1</button>

    <button id="btn">clic2</button>

    <script>

        function go() {
            console.log(this);
        }

        var btn = document.getElementById("btn");
        btn.onclick = function() {
            console.log(this)
        }

    </script>
</body>
Run Code Online (Sandbox Code Playgroud)

我有一个HTML文档,其中包含两个按钮,它们在单击时会执行相同的操作:它们记录了“ this”关键字。

我很惊讶他们没有显示出相同的结果:

对于按钮“ clic1”:this = Window

对于按钮“ clic2”:这= ID为“ btn”的按钮对象

有什么解释吗?

谢谢

tra*_*r53 5

TLDR:

go不是第一个按钮的事件处理程序。事件处理程序是由HTML解析器生成的匿名函数。在示例中,生成的处理程序恰好调用 go


HTML中提供的用于onEventName属性的JavaScript代码被编译成形式的函数

function(event) {
    // code written in the attribute value
}
Run Code Online (Sandbox Code Playgroud)

解析器以这种方式生成的函数具有一个相当奇怪的作用域链,该链包括生成的处理程序是其属性的form元素,该元素所在的任何外部元素以及document至少该对象。范围链的原因可以追溯到DOM标准化之前。提供了较旧的IE版本,window.event而不是event参数。

所以第一个按钮

 <button onclick="go()">clic1</button>
Run Code Online (Sandbox Code Playgroud)

在当前浏览器中,该按钮的onclick处理程序生成为:

 function( event) {
     go()
 }
Run Code Online (Sandbox Code Playgroud)
  • onclick处理程序是带有event参数的函数。用this按钮的值调用它。
  • go是一个普通的函数调用- this调用者的值尚未应用。您可以说,如果愿意,可以this通过调用作为参数传递go(this)
  • go是使用function关键字声明的,默认情况下具有this全局对象的值。

在第二个示例中,您将正常编译匿名函数表达式(不使用HTML解析器),并将其直接附加到第二个按钮元素。

  • 使用按钮作为其this值调用附加函数,该按钮可以记录到控制台。

  • 附加函数没有wierdo范围链。