Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #21 (permalink)  
Старый 01.10.2010, 13:45
Новичок на форуме
Отправить личное сообщение для Kolyaj Посмотреть профиль Найти все сообщения от Kolyaj
 
Регистрация: 19.02.2008
Сообщений: 9,177

А как тогда присвоить undefined? Этакое обнуление свойства.
Ответить с цитированием
  #22 (permalink)  
Старый 01.10.2010, 13:59
Профессор
Отправить личное сообщение для Sweet Посмотреть профиль Найти все сообщения от Sweet
 
Регистрация: 16.03.2010
Сообщений: 1,618

Обnullять можно присваивая null Но по уму тут нужно не "обнулять" значение, а выдергивать весь объект из массива storage: если он пустой (undefined), то и незачем по нему пробегать в цикле for.
Ответить с цитированием
  #23 (permalink)  
Старый 02.10.2010, 05:17
Интересующийся
Отправить личное сообщение для cainrus Посмотреть профиль Найти все сообщения от cainrus
 
Регистрация: 30.09.2010
Сообщений: 13

я в Вашем примере кода, попробовал не заталкивать с помощью "push" значения в массив, а использовать storage как объект, в который по ключу ставить значения:
storage[this] = newValue;


Это избавило меня от лишнего цикла.
Для меня оказалось удивительным то, что this используемый как ключ, оказался уникальным, когда его (this) используешь в едином замыкании для всех объектов, даже если объекты по существу будут одинаковыми(но не ссылками друг на друга).
Ответить с цитированием
  #24 (permalink)  
Старый 02.10.2010, 10:26
Профессор
Отправить личное сообщение для Sweet Посмотреть профиль Найти все сообщения от Sweet
 
Регистрация: 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
Ответить с цитированием
  #25 (permalink)  
Старый 02.10.2010, 11:34
Профессор
Отправить личное сообщение для Sweet Посмотреть профиль Найти все сообщения от Sweet
 
Регистрация: 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()]);
Ответить с цитированием
  #26 (permalink)  
Старый 02.10.2010, 17:11
Интересующийся
Отправить личное сообщение для cainrus Посмотреть профиль Найти все сообщения от cainrus
 
Регистрация: 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..


Перепишу фишку, используя первоначальный способ с циклом, раз нет других способов
Ответить с цитированием
  #27 (permalink)  
Старый 02.10.2010, 19:05
Профессор
Отправить личное сообщение для Sweet Посмотреть профиль Найти все сообщения от Sweet
 
Регистрация: 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.
Ответить с цитированием
  #28 (permalink)  
Старый 03.10.2010, 00:13
Интересующийся
Отправить личное сообщение для cainrus Посмотреть профиль Найти все сообщения от cainrus
 
Регистрация: 30.09.2010
Сообщений: 13

да, я понял это когда прочитал про функцию toString.

Сначала ошибочно посчитал(не проверил), что this должен преобразоваться в [Object Object](когда я его использую в качестве индекса массива), но раз ошибок не возникало(не проверял одинаково наполненные массивы), посчитал что действительно объекты помещаются в индексы(вот глупость!).
Если бы я наполнял массивы объектами, то выявил бы ошибку ещё раньше, надеюсь понятно почему :-) но, спасибо за твоё время.
Ответить с цитированием
  #29 (permalink)  
Старый 04.10.2010, 22:42
Профессор
Отправить личное сообщение для tenshi Посмотреть профиль Найти все сообщения от tenshi
 
Регистрация: 20.03.2008
Сообщений: 1,183

в нормальных языках объекты вполне можно использовать в качестве ключей.
__________________
.ня
Ответить с цитированием
  #30 (permalink)  
Старый 04.10.2010, 22:44
Профессор
Отправить личное сообщение для tenshi Посмотреть профиль Найти все сообщения от tenshi
 
Регистрация: 20.03.2008
Сообщений: 1,183

Сообщение от cainrus Посмотреть сообщение
Sweet:
Удивляюсь как вы до этого дошли. Работает так как требовалось. Первоначально я всего лишь хотел реализовать функционал для массива как в php: next, prev, current, end, reset, key. Всё застопорилось, когда я обнаружил, что внутренний указатель во всех массивах везде одинаков.
не надо так делать. это глупо. сделай так, чтобы массив возвращал итератор, у которого уже будут эти методы
__________________
.ня
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
вопр. замыкание Shaci jQuery 6 05.03.2010 12:21