【问题标题】:"this" inside event handler from HTML attribute来自 HTML 属性的事件处理程序内部的“this”
【发布时间】:2018-06-07 23:26:03
【问题描述】:

在看到这段代码之前,我以为我理解了“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>

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

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

对于按钮“clic1”:this = Window

对于按钮“clic2”:this = id 为“btn”的按钮对象

对此有什么解释吗?

谢谢

【问题讨论】:

  • Afaik,第一个按钮的 onclick 是一个执行 eval("go()") 的函数,它导致 go 丢失上下文并恢复为 window 作为上下文。这是内联代码不好的众多原因之一。

标签: javascript this handler


【解决方案1】:
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 值尚未应用。例如,如果您愿意,可以通过调用 go(this)this 作为参数传递。
  • go 是使用 function 关键字声明的,默认情况下具有全局对象的 this 值。

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

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

  • 附加的函数没有奇怪的作用域链。

【讨论】:

    猜你喜欢
    • 2023-04-03
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 2021-01-07
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多