与'prototype'混淆(Firefox扩展)

时间:2011-11-08 15:56:33

标签: javascript firefox-addon

我正在开发一个firefox扩展,我想我现在已经对Javascript产生了一个基本的误解,确切地说'原型'概念。考虑以下最小的例子,注意我设置变量this.demo和this.test:

时的差异
  var Example = new Array();

  Example.Foo = function() {
    this.test = null;
    this.demo = "World";
  };

  Example.Foo.prototype = {

    initialize : function(resource) {
      this.test = "Hello";
      this.display();
    },

    display : function() {
      alert(this.test + " " + this.demo);
    },
  }

  window.addEventListener(
    "load", 
    function() {
      window.obj = new Example.Foo();
      obj.initialize();
    }, 
    false
  );

打开Firefox时,我得到了预期的输出:

  Hello World

只要在js源文件中调用display()',就可以这样工作。但是,当我通过菜单条目中的相应点击调用display()时,例如:

...
    <menupopup id="menu_ToolsPopup">
      <menuitem label="Example" oncommand="obj.display();"/>
    </menupopup>
...

我明白了:

  null World

当然,事先已经调用了initialize()。

我仍然是Javascript的新手并使用现有代码。因此,我对目前的行为感到困惑。什么是最好的解决方案是工作?

2 个答案:

答案 0 :(得分:2)

因为this正在引用调用该方法的对象。

var MyObject= new function(){

    this.value="Hello World!";

    this.display=function(){
        alert(this.value);
    }
}

<input type="button" value="Foo Bar!" onclick="MyObject.display()"> //Foo Bar!

这个例子会警告“Foo Bar!”而不是“Hello World!”

为防止出现这种意外情况,您可以使用var that=this;

添加“检查点”
var MyObject= new function(){

    var that=this; // <--- reference to actual object

    this.value="Hello World";

    this.display=function(){
        alert(that.value);
    }

}

<input type="button" value="Foo Bar!" onclick="MyObject.display()"> //Hello World!

这将提醒“Hello World!”来自MyObject的'value'不是标签的'value'。

也许这种其他情况可以帮助您理解

<img scr="dog.gif" title="Little Dog" onclick="alert('This is a '+this.title)">

“这是一只小狗”

答案 1 :(得分:0)

经过几个小时后,我解决了我的问题...不知怎的,到目前为止我还没有完全理解。

首先,最小的例子确实有效。我有奇怪的行为,因为我将示例代码的行集成到应用程序代码中。然而,&#34;内心深处&#34;在代码中发生了一个与initialize()调用发生冲突的错误。当我将示例代码行放在应用程序代码之前时,我总是得到输出"Hello World"(在一种情况下代替"null World"

其次,应用程序存在根本性缺陷。它是一个带有补充工具栏的Firefox扩展。由此window.addEventListener(...)被调用两次,一次用于侧边栏,一次用于&#34;正常&#34;浏览器窗口。因此,我有两个单独的window.obj。代码只为侧边栏调用initialize()。 99%这不是问题,因为大多数代码使用侧栏window.obj。然而,来自上下文菜单的调用以浏览器window.obj为目标。作为一种解决方案,我改变了代码的方式,只使用了侧边栏window.obj

抱歉找错了方向。非常感谢所有答案。你的评论带回了正确的轨道,绝对让我充满动力! :)

基督教