代码之家  ›  专栏  ›  技术社区  ›  Cerebrus

重置或清除javascript对象的正确方法?

  •  3
  • Cerebrus  · 技术社区  · 16 年前

    我有一个javascript类,它包含一些函数和成员对象:

    function MyUtils()
    {
      // Member Variables (Constructor)
      var x = getComplexData();
      var y = doSomeInitialization();
    
      // Objects
      this.ParamHash = function()
      {
        // Member variables
        this.length = 0;
        this.items = new Array();
    
        // Constructor
        for (var i = 0; i < arguments.length; i += 2)
        {
          // Fill the items array.
          this.items[arguments[i]] = arguments[i+1];
          this.length++;
        }
      }
    
      // Functions
      this.doSomething = function()
      {
        // Do something.
        // Uses the items in the ParamHash object.
        for (var i in this.ParamHash.items)
        {
          // Really do something!
        }
    
        // Clear the ParamHash object -- How??
      }
    }
    

    调用方式如下:

    // First call - works fine.
    var utils = new MyUtils();
    utils.paramHash = new utils.ParamHash("a", 1, "b", 2);
    utils.doSomething();
    
    // Don't want to re-initialize.
    // utils = new MyUtils();
    
    // Consequent call - crashes ["Object doesn't support this action."].
    utils.paramHash = new utils.ParamHash("c", 3);
    utils.doSomething();
    

    问题产生于我想要重用相同的限制 utils 对象,而不必重新初始化它。另外,我希望每次调用paramhash对象时都从头开始重新创建它。但是,对paramhash构造函数的后续调用会引发一个错误“object does not support this action”。在这个阶段,我可以看到utils.paramhash对象仍然包含旧值(“a”、“b”)。

    我尝试过各种方法来清除paramhash对象,例如将其项和长度设置为空,从数组中弹出项。直到我用下面的方法 doSomething() 功能:

    this.paramHash.items = new Array();
    this.paramHash.length = 0;
    

    这似乎是错误的,因为如果我有很多成员变量…我需要单独重置它们吗? 所以,问题是:什么是重置 ParamHash 反对初始状态?我肯定希望有一个更干净/更直接的方法。比如:

    // Doesn't work! :-(
    this.paramHash = new function() {};
    

    编辑:我正在寻找一个跨浏览器的解决方案-至少在IE6+和FF 2+中有效。


    解决方案: 感谢Cristoph,我可以通过在 MyUtils 它只保存 帕拉希什 功能。

    function MyUtils()
    {
      // Same ol' stuff.
      var myParamHash;
    }
    
    // First call - works fine.
    var utils = new MyUtils();
    utils.myParamHash = new utils.ParamHash("a", 1, "b", 2);
    utils.doSomething();
    
    // Consequent call - works fine now.
    utils.myParamHash = new utils.ParamHash("c", 3);
    utils.doSomething();
    
    3 回复  |  直到 16 年前
        1
  •  3
  •   Christoph    16 年前

    这个

    utils.ParamHash = new utils.ParamHash("a", 1, "b", 2);
    

    覆盖包含 ParamHash() 具有实例对象的构造函数函数。你可以通过

    utils.ParamHash.constructor
    

    但更干净的方法是,首先不要覆盖它并使用单独的属性来保存实例。


    我不知道大脑正试图解决的确切问题,所以他所做的事情可能有正当的理由。但在我看来,他的解决方案过于复杂。我会这样做:

    function MyUtils() {
        this.x = getComplexData();
        this.y = doSomeInitialization();
        this.params = {};
    }
    
    MyUtils.prototype.doSomething = function() {
        for(var prop in this.params) {
            if(this.params.hasOwnProperty(prop)) {
                // do stuff
            }
        }
    };
    
    var utils = new MyUtils;
    utils.params = { a : 1, b : 2 };
    utils.doSomething();
    

    支票 hasOwnProperty() 如果你能确定没有人弄乱 Object.prototype .


    其他一些评论:

    • 在javascript中,通常只有构造函数的名称大写。
    • items 不应该是数组,而应该是一个普通的对象。 this.items = {};
        2
  •  2
  •   Chetan S    16 年前

    当你这样做的时候

    utils.ParamHash = new utils.ParamHash("a", 1, "b", 2);
    

    您用对象实例替换了paramhash构造函数函数。随后的 new ParamHash() 失败,因为utils.paramhash不再是构造函数函数。

    试试这个:

    var utils = new MyUtils();
    utils.paramHashInstance = new utils.ParamHash("a", 1, "b", 2);
    utils.DoSomething();
    
        3
  •  0
  •   Josh Stodola    16 年前

    你试过省略这个新关键字吗?

    utils.ParamHash = utils.ParamHash("c", 3);