2009-02-26 3 views
3

У меня есть класс Javascript, который содержит несколько функций и объектов-членов:Правильный способ сброса или очистки объекта 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 не поддерживает это действие». На этом этапе я вижу, что объект utils.paramHash по-прежнему содержит старые значения («a», «b»).

Я пробовал различные способы очистки объекта ParamHash, такие как установка его элементов и длины на нуль, появление элементов из массива. Ничто, казалось, не работать, пока я не использовал следующим образом (в функции doSomething()):

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

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

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

EDIT: Я ищу для кросса-браузерным решения - тот, который работает по крайней мере в 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(); 
+0

Я добавил более простое решение для моего ответа; не знаю, какую проблему вы пытаетесь решить, поэтому ваш код может быть лучше подходит ... – Christoph

ответ

3

Этот

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

Проверка на hasOwnProperty() не требуется, если вы можете быть уверены, что никто не перепутались с Object.prototype.


Некоторые дополнительные комментарии:

  • в JavaScript, как правило, только имена функций конструктора капитализируются
  • items не должен быть массив, но простой объект, т.е. this.items = {};
+0

Можете ли вы привести пример того, как я может использовать восстановленный конструктор (используя свойство конструктора) для сброса объекта? – Cerebrus

+0

'utils.ParamHash = utils.ParamHash.constructor' отменяет назначение, то есть после этого вы можете назначать новые значения через' utils.ParamHash = new utils. ParamHash («c», 3, «d», 4) ' – Christoph

+0

Спасибо. Я отредактировал свой вопрос, чтобы включить окончательное решение, которое я использовал. – Cerebrus

0

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

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

У меня, хотя я был бы удивлен, если бы это сработало. В нем говорится: «Ожидаемая функция». :-( – Cerebrus

+0

Если вы опускаете новое ключевое слово, оно не создает новый объект. Он просто запускает функцию-конструктор в глобальном контексте (задавая все свойства объекту окна)! –

2

если сделаете это

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

Спасибо, Четан. Это не вызывает ошибку, но затем экземпляр или параметры недоступны в функции DoSomething(), которая является частью класса. Мне нужно выполнить сброс из функции DoSomething(). – Cerebrus

+0

@Cerebrus: почему экземпляр недоступен? 'for (var i in thi s.paramHashInstance.items) 'должен отлично работать ... – Christoph

+0

Потому что я забыл создать свойство в классе MyUtils. Я добавлял свойство динамически, поскольку, как подсказывал ответ Четана, он предлагал. См. Мой отредактированный вопрос. – Cerebrus