А как тогда присвоить undefined? Этакое обнуление свойства.
|
Обnullять можно присваивая null:) Но по уму тут нужно не "обнулять" значение, а выдергивать весь объект из массива storage: если он пустой (undefined), то и незачем по нему пробегать в цикле for.
|
я в Вашем примере кода, попробовал не заталкивать с помощью "push" значения в массив, а использовать storage как объект, в который по ключу ставить значения:
storage[this] = newValue; Это избавило меня от лишнего цикла. Для меня оказалось удивительным то, что this используемый как ключ, оказался уникальным, когда его (this) используешь в едином замыкании для всех объектов, даже если объекты по существу будут одинаковыми(но не ссылками друг на друга). |
cainrus, покажи, пожалуйста, рабочий пример:)
Вообще, ключ в объекте, если кто не в курсе, - строка. Так что же ввело в заблуждение? var object = {}, innerObject = {}; object[innerObject] = {prop: 'value'}; alert(object[innerObject].prop); // value var string = innerObject.toString(); // [object Object] alert(object[string].prop); // value // А вот, что происходит на самом деле: alert(object['[object Object]'].prop); // value |
Кстати, вариант storage[this] = newValue; вполне возможен. Правда, придется залезть не только в Object.prototype, но и в метод toString. Учтите, Kolyaj не даст соврать, при этом бог убьет не только котенка, но и щеночка. Поэтому вариант с циклом мне более симпатичен:)
Object.prototype.key = (function(){ var storage = {}, count = 0; return function(value){ if(this.toString()=='[object Object]') this.toString=(function(){ var string = 'obj'+count; count++; return function(){return string;}; }()); if(arguments.length!=0){ storage[this] = value; return value; }; return storage[this]; }; }()); var FirstObject = {a:1}, SecondObject = {b:2}; FirstObject.key(100); SecondObject.key(999); alert([FirstObject.key(), SecondObject.key()]); |
Да, я обнаружил что мой код не работает правильно, когда посмотрел метод toString(). Если есть два массива с одинаковым наполнением, то ключ хранения между ними будет общий, а если хранить объекты в массиве, тогда баг проявится при одинаковом количестве объектов в массиве.
// Extending Array Object Array.prototype.key = (function(){ var storage = []; return function(key){ if ( typeof(key) !== "undefined" ) { // Add positive number or null, if key presents, and return self instance. key = parseInt(key); // If key is invalid or out of range, then it should be null. if (key < 0 || key > this.length - 1 || isNaN(key)) key = null; storage[this] = key; return this; } else { // Return key key = storage[this]; // If key is undefined, then it should be null. if (typeof(key) === "undefined") key = null; return key; } // Get value; if value is not defined, then set it to null. if (typeof(value = storage[this]) === "undefined") value = null; // Return index of array or null if array is empty return value; } }()); // Let's test two new arrays SomeArray = [1,2,3,4,5,6,7,8,9]; AnotherArray = ['a','b','c','d','e','f','g']; BonusArray = ['a','b','c','d','e','f','g']; // key method should return key index alert('SomeArray key = '+SomeArray.key()); //null, there is no index yet SomeArray.key(2); // set first array index to 2 AnotherArray.key(5); // set second array index to 5 alert('SomeArray key = '+SomeArray.key()); // 2 ! alert('AnotherArray key = '+AnotherArray.key()); // 5 ! alert('BonusArray key = '+BonusArray.key()); // 5 ! but it should not.. Перепишу фишку, используя первоначальный способ с циклом, раз нет других способов :) |
Не, ты явно не понял сути конструкции типа storage[this]!!!
Вот смотри, почему у тебя возникает "баг" (это не баг, просто функция криво написана): Когда ключ - объект, он приводится к строке методом toString(). У массива в таком случае возвращается строка со значениями через запятую. Так вот что у тебя происходит. alert('SomeArray key = '+SomeArray.key()); //функция смотрит storage['1,2,3,4,5,6,7,8,9']. Его нет. SomeArray.key(2); //функция устанавливает storage['1,2,3,4,5,6,7,8,9'] = 2 AnotherArray.key(5); //устанавливает storage['a,b,c,d,e,f,g'] = 5 alert('SomeArray key = '+SomeArray.key()); //смотрим storage['1,2,3,4,5,6,7,8,9']. Там значение 2 alert('AnotherArray key = '+AnotherArray.key()); //смотрим storage['a,b,c,d,e,f,g']. Там значение 5 alert('BonusArray key = '+BonusArray.key()); //BonusArray.toString() = 'a,b,c,d,e,f,g'. //смотрим storage['a,b,c,d,e,f,g']. Там значение 5 //Вот и весь "баг" |
да, я понял это когда прочитал про функцию toString.
Сначала ошибочно посчитал(не проверил), что this должен преобразоваться в [Object Object](когда я его использую в качестве индекса массива), но раз ошибок не возникало(не проверял одинаково наполненные массивы), посчитал что действительно объекты помещаются в индексы(вот глупость!). Если бы я наполнял массивы объектами, то выявил бы ошибку ещё раньше, надеюсь понятно почему :-) но, спасибо за твоё время. |
в нормальных языках объекты вполне можно использовать в качестве ключей.
|
Цитата:
|
Часовой пояс GMT +3, время: 05:15. |