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

发布于 2024-07-14 18:33:33 字数 2252 浏览 7 评论 0原文

我有一个 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 构造函数的后续调用会引发错误“对象不支持此操作”。 在这个阶段,我可以看到 utils.paramHash 对象仍然包含旧值(“a”,“b”)。

我尝试了各种方法来清除 ParamHash 对象,例如将其项目和长度设置为 null,从数组中弹出项目。 直到我使用以下方式(在 doSomething() 函数中)之前,似乎什么都不起作用:

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

这似乎是错误的,因为如果我有很多成员变量怎么办......我是否必须重置它们中的每一个单独? 所以,问题是:将 ParamHash 对象重置为初始状态的最佳方法是什么? 我确信希望有一种更干净/更直接的方式。 类似于:

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

编辑:我正在寻找一种跨浏览器解决方案 - 至少可以在 IE6+ 和 FF 2+ 中运行的解决方案。


解决方案: 感谢 Cristoph,我能够通过在 MyUtils 中创建一个单独的变量/属性来完成此操作,该变量/属性仅保存 ParamHash 函数的实例。

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();

I have a Javascript class that contains a few functions and member objects:

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??
  }
}

This is invoked in the following manner:

// 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();

The problem arises from the restriction that I want to reuse the same utils object throughout the code without having to re-initialize it. Also, I want the ParamHash object to be recreated from scratch everytime I call it. However, consequent calls to the ParamHash constructor throw an error "Object doesn't support this action." At this stage, I can see that the utils.paramHash object still contains the old values ("a", "b").

I have tried various ways to clear the ParamHash object such as setting it's items and length to null, popping items from the array. Nothing seemed to work until I used the following way (in the doSomething() function):

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

This seems wrong because what if I had a lot of member variables... would I have to reset each of them individually?
So, the question is: What is the best way to reset the ParamHash object to the initial state? I'm sure hoping that there is a cleaner/more direct way. Something like :

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

EDIT: I'm looking for a cross-browser solution - One that works atleast in IE6+ and FF 2+.


Solution: Thanks to Cristoph, I was able to do it by creating a separate variable/property within MyUtils which only holds the instance of the ParamHash function.

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();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤星 2024-07-21 18:33:33

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

会用实例对象覆盖保存 ParamHash() 构造函数的属性。 您可以通过返回构造函数

utils.ParamHash.constructor

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


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

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();

如果您可以确定没有人弄乱Object.prototype,则没有必要检查hasOwnProperty()


一些补充说明:

  • 在 JavaScript 中,通常只有构造函数的名称是大写的
  • items 不应该是数组,而应该是普通对象,即 this.items = {};

This

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

overwrites the the property which holds the ParamHash() constructor function with an instance object. You could get the constructor back via

utils.ParamHash.constructor

but the cleaner way would be to not overwrite it in the first place and use a seperate property to hold the instance.


I don't know the exact problem Cerebrus is trying to solve, so there might be valid reasons for what he's doing. But in my opinion, his solution is overly complicated. I'd do something like this:

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();

The check for hasOwnProperty() is unnecessary if you can be sure that no one messed with Object.prototype.


Some additional comments:

  • in JavaScript, normally only the names of constructor functions are capitalized
  • items shouldn't be an array, but a plain object, ie this.items = {};
甚是思念 2024-07-21 18:33:33

当您这样做时,

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();

when you did this

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

you replaced the ParamHash constructor function with an object instance. Subsequent new ParamHash() fails because utils.ParamHash is no longer a constructor function.

Try this:

var utils = new MyUtils();
utils.paramHashInstance = new utils.ParamHash("a", 1, "b", 2);
utils.DoSomething();
红墙和绿瓦 2024-07-21 18:33:33

您是否尝试过省略 new 关键字?

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

Have you tried omitting the new keyword?

utils.ParamHash = utils.ParamHash("c", 3);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文