Создание массива-подобного объекта JavaScript, который можно использовать как массив и объект

Можно ли создать объект, который можно использовать как массив и объект?

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

var ALO = {
  db: {}
};
Object.defineProperty(ALO, 'length', {
  get: function() {
    var count = 0;
    for (var prop in ALO.db) {
      if (ALO.db.hasOwnProperty(prop)) count++;
    }
    return count;
  },
  enumerable: false
});

function add(baseObj, obj) {
  for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      if (!isNaN(prop)) {
        //create a default string begining with i
        baseObj.db["i" + prop] = obj[prop];
      } else {
        baseObj.db[prop] = obj[prop];
      }

      Object.defineProperty(baseObj, prop, {
        get: function() {
          return baseObj.db[prop];
        },
        set: function(newValue) {
          baseObj.db[prop] = newValue;
        },
        enumerable: false,
        configurable: true
      });

      Object.defineProperty(baseObj, baseObj.length - 1, {
        get: function() {
          return baseObj.db[prop];
        },
        set: function(newValue) {
          baseObj.db[prop] = newValue;
        },
        enumerable: false,
        configurable: true
      });
    }
  }
}

add(ALO, {
  "myprop": "myvalue"
});
document.write(ALO["myprop"] + "<br>");
ALO[0] = "mynewvalue";
document.write(ALO["myprop"] + "<br>");
ALO["myprop"] = "mynewervalue";
document.write(ALO["myprop"]);

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

ALO[1] = "create and assign this string";

или же

ALO["somenonexistingprop"] = "another string";

1 ответ

Я верю, что вы найдете это нормально Arrays в JavaScript наследуют от Object Это означает, что вы можете злоупотреблять ими как обычными объектами, если хотите.

let MyArray = [1, 2, 3];
console.log('let MyArray = [1, 2, 3];');

console.log('Typeof MyArray = ', typeof(MyArray));

console.log('Wait.....');

console.log('So can I just assign stuff to an array like an object?');

MyArray['key'] = 'value';
console.log(`MyArray.key = 'value';`);
console.log('console.log(MyArray.key) =>', JSON.stringify(MyArray.key));

console.log('Keys:', JSON.stringify(Object.keys(MyArray)));
console.log('Array Length:', MyArray.length);

console.log('TADA, the standard browser Array does what you want');

Вероятно, есть причины не делать этого, кроме того, что это сильно сбивает с толку, но я считаю, что это будет соответствовать вашим требованиям и не требует кода!

РЕДАКТИРОВАТЬ: После прочтения некоторых комментариев ниже сгиба кажется, что ОП по какой-то причине хочет получить доступ к свойствам, добавленным в Object режим как члены массива. Если вам это нужно, вы можете просто использовать Object.keys(MyArray) вместо MyArray как показано в последних строках вывода консоли выше.

Другие вопросы по тегам