提问人:AntonBoarf 提问时间:6/7/2018 最后编辑:decezeAntonBoarf 更新时间:8/26/2022 访问量:440
HTML 属性事件处理程序中的“this”
"this" inside event handler from HTML attribute
问:
我以为我理解了“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” 的按钮对象
对此有什么解释吗?
谢谢
答:
顶级域名:
go
不是第一个按钮的事件处理程序。事件处理程序是由 HTML 解析器生成的匿名函数。在此示例中,生成的处理程序恰好调用 .go
HTML 中为属性提供的 JavaScript 代码被编译为表单函数onEventName
function(event) {
// code written in the attribute value
}
解析器以这种方式生成的函数具有一个相当奇怪的作用域链,其中包括生成的处理程序是其属性的元素、元素所在的任何外部表单
元素以及文档
对象。作用域链的原因可以追溯到 DOM 标准化之前。较旧的 IE 版本提供了 window.event
而不是 event
参数。
所以第一个按钮
<button onclick="go()">clic1</button>
在当前浏览器中,将按钮的 onClick 处理程序生成为:
function( event) {
go()
}
onclick 处理程序是采用参数的函数。它使用按钮的值进行调用。
event
this
go
是普通函数调用 - 调用方的值尚未应用。比如说,如果你愿意,你可以通过调用来传递参数。this
this
go(this)
go
使用关键字声明,默认情况下具有全局对象的值。function
this
如果必须在 HTML 中附加一个 [] 函数才能像事件处理程序一样调用,请在开始标记中添加一个属性,例如
myHandler
oneventname = "myHandler.call(this, event)"
或者,如果
this
值不是必需的,只需oneventname="myHandler(event);
在第二个示例中,您正常编译一个匿名函数表达式(不使用 HTML 解析器),并将其直接附加到第二个按钮元素。
调用附加函数时,按钮作为其值,可以记录到控制台。
this
附加的函数没有 Wierdo 作用域链。
评论
eval("go()")
go
window