Как решить "TypeError: array.splice не является функцией", когда "var array = {}"?

Возможный дубликат:
Как удалить свойство из объекта javascript
Эквивалент JavaScript Hashmap

Я использую jQuery, и я обрабатываю переменную следующим образом:

var array = {};

array[an_object]      = something
array[another_object] = something_else
array[...]            = ...

Когда я пытаюсь запустить метод splice на array, я получаю a TypeError: array.splice is not a function. Я намерен удалить ключ an_object и весь его контент из переменной array.

Как я могу это сделать?


Примечание. Когда я запускаю console.log(array[an_object]) (то же самое верно для another_object и всех других объектов), я получаю:

[Object { label="str1",  value=1 }, Object { label="str2",  value=2 }, { label="strN",  value=N }]

Ответ 1

Прежде всего, назовите свои переменные такими, какие они есть. Имя array, которое вы используете, вводит в заблуждение, если вы используете его для создания объекта.

var myObject = {};

myObject[an_object]      = "xyz";
myObject[another_object] = "abc";

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

delete myObject[an_object]; // Returns true / false if the deletion is a success / failure
console.log(myObject[an_object]) // Returns undefined

Теперь, сказав это, это не будет работать так, как вы ожидали. myObject[an_object] будет содержать "abc"
Не используйте объекты в качестве ключей. Вместо этого используйте строки.
Это связано с тем, что любой параметр, введенный в [], будет преобразован в строку. Итак, вы входите myObject["[object Object]"]

Ответ 2

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

var array = {};

array['an_object'] = "something"
array['another_object'] = "something_else"

delete(array.an_object)

console.log(array) // Object { another_object = "something_else" }

ИЗМЕНИТЬ

Как указано в комментариях, если проблема заключается в том, что объекты используются как ключи для другого объекта (в этом случае путано называются array), тогда проблема в том, что объект сначала преобразуется в это строковое представление, которое будет использоваться в контексте ключа объекта. Поэтому все объекты, используемые в качестве ключей, будут фактически ссылаться на один ключ с именем [object Object], и какой бы объект, который вы используете в качестве ключа, не перезапишет предыдущие.

В примере в вопросе...

array[an_object]      = something
array[another_object] = something_else
// array: Object { "[object Object]" = "something_else" }

Ответ 3

Чтобы достичь Словаря в простом JavaScript, довольно сложно, вам нужно будет создать весь конструктор для обработки этого - или использовать библиотеку, которая будет обрабатывать это для вас.

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

В качестве простой альтернативы вы можете сделать следующее:

function pushToObject(obj, key, value){
  if( !key||!obj ) return false;
  if( !key[''] ) {
    pushToObject.index = pushToObject.index||[];
    key[''] = pushToObject.index.length;
    pushToObject.index.push(key);
  }
  obj[key['']] = value;
  return true;
}

function removeFromObject(obj, key){
  if( !isNaN(key) ) {
    var list = listKeyObjects(obj);
    var item = list[key];
    return removeFromObject(obj,item);
  }
  else if(key) {
    if( !key[''] ){
      return false;
    }
    return delete obj[key['']];
  }
  return false;
}

function listKeyObjects(obj){
  var a = [];
  for(var i in obj){
    a.push(pushToObject.index[i]);
  }
  return a;
}

Использование

var array = {}; /// it would be best to change the name of this object
var an_object = {}, another_object = {};

/// add your items to the array object, this handles giving each of your
/// objects used as a key a unique index property. This does mean the objects
/// you use `an_object`, `another_object` are modified.
pushToObject( array, an_object, 'something else' );
pushToObject( array, another_object, 'something other than else' );

console.log(array); /// {0:'something else',1:'something other than else'}

removeFromObject( array, an_object ); /// remove using an object as a key

console.log(array); /// {1:'something other than else'}

removeFromObject( array, 0 ); /// remove using an offset index

console.log(array); /// {}

после мыслей

Очевидно, что лучшим вариантом является создание для этого собственного выделенного конструктора, но вы могли бы улучшить выше с помощью немного большего количества кода, чтобы он не изменял ключевые объекты. Вместо этого всякий раз, когда вы работаете с объектом в качестве ключа, вы можете сканировать pushToObject.index для смещения вашего ключевого объекта. Я решил пойти на версию, которая изменяет ваши ключевые объекты, тем не менее, поскольку она должна функционировать быстрее, чем при сканировании списка при каждом изменении массива.

получить ключевую функцию

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

function getKeyObjectAtIndex = function(obj, index){
  var list = listKeyObjects(obj);
  return list[index] ? list[index] : null;
}

console.log(array); /// {0:'something else',1:'something other than else'}

var key = getKeyObjectAtIndex(array, 1);

console.log(key === another_object) /// === TRUE

Ответ 4

Может быть, так:

Fiddle

var array = {};

var an_object = {};

var another_object = {};    

array[an_object] = 'something'

array[another_object] = 'something_else'

alert(array[an_object]);

array[an_object] = null;

alert(array[an_object]);

delete array[an_object]

alert(array[an_object]);

Ответ 5

Вы не можете использовать метод массива для объектов. В вашем случае вы создали объектный литерал вместо массива, определите его как var a = [] ИЛИ var a = new Array();

Надеюсь, что это поможет!