"这"来自HTML属性的内部事件处理程序

时间:2018-06-07 13:38:52

标签: javascript this handler

我以为我理解了这个"这个"关键字,直到我看到这段代码:

<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>

我有一个带有两个按钮的HTML文档,它们在点击时会执行相同的操作:它们会记录&#34;这个&#34;关键字。

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

对于按钮&#34; clic1&#34; :this = Window

对于按钮&#34; clic2&#34; :this = id为#34; btn&#34;

的按钮对象

有没有解释?

谢谢

1 个答案:

答案 0 :(得分:4)

TLDR:

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

HTML中为onEventName属性提供的JavaScript代码被编译为表单

的函数
function(event) {
    // code written in the attribute value
}

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

所以第一个按钮

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

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

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

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

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

  • 附加功能没有wierdo范围链。