Правильный способ сбросить или очистить объект Javascript? - PullRequest
3 голосов
/ 26 февраля 2009

У меня есть класс 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, например, устанавливая его элементы и длину равными нулю, выталкивая элементы из массива. Ничто не работало, пока я не использовал следующий способ (в функции doSomething()):

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

Это кажется неправильным, потому что, если бы у меня было много переменных-членов ... пришлось бы мне сбрасывать каждую из них по отдельности? Итак, вопрос: каков наилучший способ вернуть объект ParamHash в исходное состояние? Я уверен, что надеюсь, что есть более чистый / более прямой путь. Что-то вроде:

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

РЕДАКТИРОВАТЬ: Я ищу кросс-браузерное решение, которое работает по крайней мере в IE6 + и FF 2 +.


Решение: Благодаря Кристофу я смог сделать это, создав отдельную переменную / свойство в 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();

Ответы [ 3 ]

3 голосов
/ 26 февраля 2009

Это

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 голосов
/ 26 февраля 2009

когда ты это сделал

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();
0 голосов
/ 26 февраля 2009

Вы пытались опустить новое ключевое слово?

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