<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。