Javascript 将特定上下文绑定到函数:为什么我的;“黑客”;工作
在JavaScript忍者的秘密清单5.7(第100页)中,断言失败:Javascript 将特定上下文绑定到函数:为什么我的;“黑客”;工作,javascript,Javascript,在JavaScript忍者的秘密清单5.7(第100页)中,断言失败: <body> <button id="test">Click Me!</button> <script> var button = { clicked = false; click: function(){ this.clicked = true; assert(button.clicked, "The butto
<body>
<button id="test">Click Me!</button>
<script>
var button = {
clicked = false;
click: function(){
this.clicked = true;
assert(button.clicked, "The button has been clicked");
}
};
var elem = document.getElementById("test");
elem.addEventListener("click", button.click, false);
</script
我不明白它为什么会起作用,如果能回答这个问题,扩展我的JavaScript知识,我将不胜感激。使用
按钮。单击会起作用,因为按钮
引用了您的对象,所以您可以设置并检查。单击的属性
最后一个使用this.clicked
的示例似乎只起作用,因为它允许assert()
通过,但实际上没有设置。单击了按钮
对象的属性,因为this
不等于按钮。它实际上是在设置并测试。单击窗口上的属性
,因为如果不绑定上下文,此将(对于显示的代码)引用窗口
如果你正在读的书没有以你能理解的方式解释这个
,那么也许这本书会有所帮助。这是因为这个
的难以捉摸的本质。例如:
function someFunction(){
//In this context "this" refers to the window object, so you're setting
//clicked = true on window, not button!
this.clicked = true;
}
要解决有效的示例,请执行以下操作:
click: function(){
button.clicked = true;
assert(button.clicked, "The button has been clicked");
}
上述方法之所以有效,是因为您直接通过button.clicked重新选择按钮变量。这很有效。不可能有误解。这就像在满是人的房间里说“嗨,约翰!”而不是说“嗨,你!”并希望正确的人回应
click: function(){
this.clicked = true;
assert(this.clicked, "The button has been clicked");
}
在这里,上述方法是有效的,因为您在相同的上下文中使用它。这是指函数,因此此处单击的变量实际上是在窗口中设置的。但是因为您在断言中也引用了相同的this
,所以它是有效的
经验法则是,此
引用当前对象。如果您进行的调用不在对象内部,则您处于全局范围的上下文中,此
引用窗口对象。这是我今天学到的。谢谢大家
编辑:根据NNNN的评论更正错误。assert(此==按钮,“oops”)
tl;dr:这是因为在这两种情况下,在写入和读取单击的属性时,您都在访问同一个对象<代码>按钮===按钮
和此===此
,但按钮!==此
此
将不会引用函数本身,而是窗口
“此引用函数”-不,不会。您现在为函数指定了一个名称的事实并没有改变这样一个事实,即此
不会引用函数本身,它仍然是窗口
。this
的价值与函数是否匿名无关。“我尽量避免过多使用this
”这是一个错误的建议。这可能会很快导致难以重用的紧密耦合代码。更好地了解这个
是如何工作的,它没有那么复杂,而且99%的时间你完全可以控制这个
所指的内容。它本身并不是一个建议,更多的是个人偏好。你说得对,最好是学习这个的不同方面!谢谢大家的讨论。这有助于:)
click: function(){
this.clicked = true;
assert(this.clicked, "The button has been clicked");
}