Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将特定上下文绑定到函数:为什么我的;“黑客”;工作_Javascript - Fatal编程技术网

Javascript 将特定上下文绑定到函数:为什么我的;“黑客”;工作

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

在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 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");
 }