А как тогда присвоить 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, время: 21:10. |