Можете ли вы использовать пользовательские объекты в качестве свойств объекта в JavaScript? - PullRequest
1 голос
/ 05 ноября 2011

Предположим, я создаю пользовательский объект / javascript "class" (airquotes) следующим образом:

// Constructor
function CustomObject(stringParam) {
  var privateProperty = stringParam;

  // Accessor
  this.privilegedGetMethod = function() {
    return privateProperty;
  }

  // Mutator
  this.privilegedSetMethod = function(newStringParam) {
    privateProperty = newStringParam;
  }
}

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

var customObjectInstance1 = new CustomObject('someString');
var customObjectInstance2 = new CustomObject('someOtherString');
var customObjectInstance3 = new CustomObject('yetAnotherString');

myListOfCustomObjects[customObjectInstance1] = true;
myListOfCustomObjects[customObjectInstance2] = true;
myListOfCustomObjects[customObjectInstance3] = true;

и удалить пользовательские объекты из списка с помощью

delete myListOfCustomObjects[customObjectInstance1];

но если я попытаюсь перебрать список с помощью

for (i in myListOfCustomObjects) {
  alert(i.privilegedGetMethod());
}

, я получу ошибку в консоли FireBug, которая говорит: «i.privilegedGetMethod () не является функцией».Есть ли способ исправить эту проблему или идиома в JavaScript, чтобы сделать то, что я хочу?Извините, если это глупый вопрос, но я новичок в javascript и поищу в интернете решения моей проблемы безрезультатно.Буду признателен за любую помощь!

PS Я понимаю, что мой пример очень упрощен, и я могу просто сделать privateProperty общедоступным, используя this.property или что-то еще, но тогда я все равно получу неопределенное в предупреждениихотел бы сохранить его в капсуле.

Ответы [ 3 ]

1 голос
/ 05 ноября 2011

i не будет исходным объектом, как вы ожидали:

for (i in myListOfCustomObjects) {
    alert(typeof i); // "string"
}

Это потому, что все ключи в JavaScript являются строками.Любая попытка использовать другой тип в качестве ключа сначала будет сериализована как toString().

Если результат toString() не является уникальным для каждого экземпляра, все они будут одинаковыми ключами:

function MyClass() { }
var obj = {};

var k1 = new MyClass();
var k2 = new MyClass();

obj[k1] = {};
obj[k2] = {};

// only 1 "[object Object]" key was created, not 2 object keys
for (var key in obj) {
    alert(key);
}

Чтобы сделать их уникальными, определите пользовательский toString:

function CustomObject(stringParam) {
    /* snip */

    this.toString = function () {
        return 'CustomObject ' + stringParam;
    };
}

var obj = {};
var k1 = new CustomObject('key1');
var k2 = new CustomObject('key2');

obj[k1] = {};
obj[k2] = {};

// "CustomObject key1" then "CustomObject key2"
for (var key in obj) {
    alert(key);
}

[Редактировать]

Используя пользовательский toString, вы можете установить объект какСериализованный ключ и значение для его организации и продолжения доступа к ним:

var customObjectInstance1 = new CustomObject('someString');
var customObjectInstance2 = new CustomObject('someOtherString');
var customObjectInstance3 = new CustomObject('yetAnotherString');

myListOfCustomObjects[customObjectInstance1] = customObjectInstance1;
myListOfCustomObjects[customObjectInstance2] = customObjectInstance2;
myListOfCustomObjects[customObjectInstance3] = customObjectInstance3;

for (i in myListOfCustomObjects) {
  alert(myListOfCustomObjects[i].privilegedGetMethod());
}
1 голос
/ 05 ноября 2011
myListOfCustomObjects =[ 
            new CustomObject('someString'),
            new CustomObject('someOtherString'),
            new CustomObject('yetAnotherString')
]

вы получите доступ к любому элементу по индексу массива.

1 голос
/ 05 ноября 2011

Итерационная переменная for - это просто индекс, а не сам объект.Так что используйте:

for (i in myListOfCustomObjects) {
  alert(myListOfCustomObjects[i].privilegedGetMethod());
}

и, на мой взгляд, если вы используете объект в качестве индекса / хэша массива, он просто будет преобразован в строку «Объект», которая заканчивается в списке содна запись, потому что все ключи одинаковы («Объект»).

...