01.10.2010, 13:45
|
Новичок на форуме
|
|
Регистрация: 19.02.2008
Сообщений: 9,177
|
|
А как тогда присвоить undefined? Этакое обнуление свойства.
|
|
01.10.2010, 13:59
|
Профессор
|
|
Регистрация: 16.03.2010
Сообщений: 1,618
|
|
Обnullять можно присваивая null Но по уму тут нужно не "обнулять" значение, а выдергивать весь объект из массива storage: если он пустой (undefined), то и незачем по нему пробегать в цикле for.
|
|
02.10.2010, 05:17
|
Интересующийся
|
|
Регистрация: 30.09.2010
Сообщений: 13
|
|
я в Вашем примере кода, попробовал не заталкивать с помощью "push" значения в массив, а использовать storage как объект, в который по ключу ставить значения:
storage[this] = newValue;
Это избавило меня от лишнего цикла.
Для меня оказалось удивительным то, что this используемый как ключ, оказался уникальным, когда его ( this) используешь в едином замыкании для всех объектов, даже если объекты по существу будут одинаковыми(но не ссылками друг на друга).
|
|
02.10.2010, 10:26
|
Профессор
|
|
Регистрация: 16.03.2010
Сообщений: 1,618
|
|
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
|
|
02.10.2010, 11:34
|
Профессор
|
|
Регистрация: 16.03.2010
Сообщений: 1,618
|
|
Кстати, вариант 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()]);
|
|
02.10.2010, 17:11
|
Интересующийся
|
|
Регистрация: 30.09.2010
Сообщений: 13
|
|
Да, я обнаружил что мой код не работает правильно, когда посмотрел метод 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..
Перепишу фишку, используя первоначальный способ с циклом, раз нет других способов
|
|
02.10.2010, 19:05
|
Профессор
|
|
Регистрация: 16.03.2010
Сообщений: 1,618
|
|
Не, ты явно не понял сути конструкции типа 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
//Вот и весь "баг"
Последний раз редактировалось Sweet, 02.10.2010 в 22:55.
|
|
03.10.2010, 00:13
|
Интересующийся
|
|
Регистрация: 30.09.2010
Сообщений: 13
|
|
да, я понял это когда прочитал про функцию toString.
Сначала ошибочно посчитал(не проверил), что this должен преобразоваться в [Object Object](когда я его использую в качестве индекса массива), но раз ошибок не возникало(не проверял одинаково наполненные массивы), посчитал что действительно объекты помещаются в индексы(вот глупость!).
Если бы я наполнял массивы объектами, то выявил бы ошибку ещё раньше, надеюсь понятно почему :-) но, спасибо за твоё время.
|
|
04.10.2010, 22:42
|
Профессор
|
|
Регистрация: 20.03.2008
Сообщений: 1,183
|
|
в нормальных языках объекты вполне можно использовать в качестве ключей.
__________________
.ня
|
|
04.10.2010, 22:44
|
Профессор
|
|
Регистрация: 20.03.2008
Сообщений: 1,183
|
|
Сообщение от cainrus
|
Sweet:
Удивляюсь как вы до этого дошли. Работает так как требовалось. Первоначально я всего лишь хотел реализовать функционал для массива как в php: next, prev, current, end, reset, key. Всё застопорилось, когда я обнаружил, что внутренний указатель во всех массивах везде одинаков.
|
не надо так делать. это глупо. сделай так, чтобы массив возвращал итератор, у которого уже будут эти методы
__________________
.ня
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
вопр. замыкание |
Shaci |
jQuery |
6 |
05.03.2010 12:21 |
|
|
|