Javascript - Scopes


<script type="text/javascript">
function BigComputer(answer) {
   this.the_answer = answer;
   this.ask_question = function () {
   alert(this.the_answer);
   }
}
 function addhandler() {
   var deep_thought = new BigComputer(42),
   the_button = document.getElementById('thebutton');
   the_button.onclick = deep_thought.ask_question;
}
window.onload = addhandler;
 </script> 

为什么此脚本返回 undefined 而不是 42?这就是我理解的方式:
1)在网页加载时,我们运行"添加处理程序"方法。
2)在此方法中,我们为deep_thought变量创建BipComputer的实例。我们还在答案处设置了 42(BipComputer 类中的公共变量)
3)然后我们为按钮设置引用(在html文件中)
4)按钮在点击时激活,魔术来了:
在我看来应该打印出数字 42,因为我们刚刚在步骤 2 中为此进行了设置,但没有变量是"未定义"?

另一个问题是,在没有 ()(没有要传递的参数时)和 () 的情况下运行方法有什么区别。[像添加处理程序方法]。

也许这个问题很简单,但我曾经用java和php编程,现在面向javascript编程的思维方式对我来说很奇怪。函数看起来像类,类看起来像函数,没有真正的构造函数之类的东西。
但没关系,让我们回到:)的问题
我真的很感激任何帮助。




@Edit

多亏了@lbstr我找到了有用的链接,适合每个和我问同样问题的人。http://web.archive.org/web/20080209105120/http://blog.morrisjohns.com/javascript_closures_for_dummies

当触发单击处理程序时,this是按钮。以下是您要执行的操作:

function BigComputer(answer) {
    this.the_answer = answer;
    var self = this;
    this.ask_question = function() {
        alert(self.the_answer);
    };
}

这一切都是通过闭合的奇妙而实现的。许多js粉丝都认为这是该语言最好的部分。阅读所有关于他们的信息。

区分范围和this很重要。尽管变量由函数作用域限定,但在给定的作用域链中this不一定相同。一个简单的例子是,我可以使用我想要的任何this值调用我想要的任何函数:

someFunc.call(someThis); // call someFunc, using someThis for this

对于事件处理程序,this通常是事件源自的元素。这很好,因为页面上可能有几个按钮,并且您想对单击的按钮执行某些操作。

问题是在你分配之后

the_button.onclick = deep_thought.ask_question;

单击按钮时,将调用分配给 onclick 属性的函数,并将this绑定到按钮。您可以通过(至少)三种方式解决问题:

  • 通过重写函数(如 lbstr 的答案)

  • 通过使用 bind 创建一个以所需this执行ask_question的新函数:

    the_button.onclick = deep_thought.ask_question.bind(deep_thought);
    

    请注意,bind是 JS 1.8.5 的新增功能;上面的链接有一个用于旧 JS 引擎的填充程序。

  • 通过编写闭包来获得ask_question内部的正确this

    the_button.onclick = function() { deep_thought.ask_question(); };
    

    编辑:正如RobG在评论中指出的那样,此代码在某些浏览器中(特别是MSIE的许多版本)中创建了内存泄漏。解决方法是完全消除变量the_button

    document.getElementById('thebutton').onclick = function() {
        deep_thought.ask_question();
    };
    

    有关其他方法,请参阅本教程。

当您分配要从按钮单击执行的 ask_question() 时,"this"将是按钮的上下文,而不是基于构造函数的 this deep_thought变量。如果您从this.the_answer中删除"this"并使其仅为var,您将获得警报42。

相关内容

  • 没有找到相关文章

最新更新