3
<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)在网页加载时,我们运行“addhandler”方法。
2) 在这个方法中,我们为 deep_thought 变量创建 BipComputer 的实例。此外,我们在答案中设置了 42(BipComputer 类中的公共变量)
3)然后我们为按钮设置了引用(在 html 文件中)
4)按钮在点击时处于活动状态,这就是魔法:
在我看来应该打印出编号 42,因为我们刚刚在步骤 2 中为此进行了设置,但是变量是“未定义”?

另一个问题是,在没有 ()(没有要传递的参数时)和使用 () 的情况下运行方法有什么区别。[像 addhandler 方法]。

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




@编辑

感谢@lbstr,我找到了有用的链接,对于每个和我问同样问题的人来说。 http://web.archive.org/web/20080209105120/http://blog.morrisjohns.com/javascript_closures_for_dummies

4

3 回答 3

6

当点击处理程序被触发时,this是按钮。这是您想要执行的操作:

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

这一切都得益于闭包的美妙之处。许多 js 爱好者都同意这是该语言最好的部分。阅读所有关于他们的信息

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

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

对于事件处理程序,this通常是事件起源的元素。这很好,因为您可能在页面上有多个按钮,并且您想对被点击的那个做一些事情。

于 2013-10-15T22:18:29.157 回答
4

问题是在你分配之后

the_button.onclick = deep_thought.ask_question;

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

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

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

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

    请注意,这bind是 JS 1.8.5 的新内容;上面的链接有一个适用于旧 JS 引擎的垫片。

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

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

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

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

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

于 2013-10-15T22:41:50.243 回答
0

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

于 2013-10-15T22:34:37.610 回答