Цепочка функций в JavaScript?

Я хочу создать функцию, которая добавляет элемент в мой объект localStorage. Например.:

alert(localStorage.getItem('names').addItem('Bill').getItem('names'));

Первый метод — это getItem, который получает элемент для объектов localStorage... но addItem будет пользовательской функцией. Эта цепочка функций, наконец, предупредит Билла.

Итак, как мне сделать эту цепочку функций для localStorage?


person Oscar Godson    schedule 04.07.2010    source источник
comment
Это не имеет никакого смысла. Что getItem вернет?   -  person SLaks    schedule 05.07.2010
comment
getItem должен быть в конце цепочки, но кроме этого это можно сделать   -  person gblazex    schedule 05.07.2010
comment
Разве это не должно быть просто alert(localStorage.getItem('names').addItem('Bill')).   -  person Lèse majesté    schedule 05.07.2010
comment
Да, это тоже сработает, если вернут все имена, включая Билла...   -  person Oscar Godson    schedule 06.07.2010


Ответы (4)


Это возможно, если вы создаете объект-оболочку/декоратор, который делает возможной цепочку. Например, так работает jQuery. Но в данном случае это бесполезно.

Однако я сделал возможную реализацию.

Но getItem разорвет цепочку (поэтому его всегда следует использовать в конце).

storage().setItem('names', 'Bill').getItem('names'); // or
storage().setItem('names').addItem('Bill').getItem('names'); // or
storage().key('names').value('Bill').set().get('names');

Реализация

(function( window, undefined ) {

var storage = function( key, value ) {
  return new storage.init( key, value );
};

storage.init = function( key, value ) {
  this._key   = key;
  this._value = value;
};

storage.init.prototype = {

  key: function( key ) {
    this._key = key;
    return this;
  },

  value: function( value ) {
    this._value = value;
    return this;
  },

  get: function( key ) {
    key = isset(key) || this._key;
    return localStorage.getItem( key );
  },

  set: function( key, value ) {
    this._key   = key   = isset(key)   || this._key;
    this._value = value = isset(value) || this._value;
    if ( key && value ) {
      localStorage.setItem( key, value );
    }
    return this;
  },

  addItem: function( value ) {
    this._value = isset(value) || this._value;
    if ( this._key && value !== undefined ) {
      localStorage.setItem( this._key, value );
    }
    return this;
  },

  // aliases...
  getItem: function( key ) {
    return this.get( key );
  },
  setItem: function( key, value  ) {
    return this.set( key, value );
  }
};

function isset( value ) {
  return value !== undefined ? value : false;
}

window.storage = storage;

})( window );
person gblazex    schedule 04.07.2010
comment
Спасибо большое, наверное, я что-то напутал. Я копирую и вставляю ваш код, а затем добавляю alert(storage.setItem('names').addItem('Bill').getItem('names')); прямо под ним, и я получаю storage.setItem, это не функция? - person Oscar Godson; 06.07.2010
comment
@Oscar – Вы забыли скобки: alert(storage().setItem('names').addItem('Bill').getItem('names')) - person Marcel Korpel; 06.07.2010
comment
@Oscar Marcel прав, теперь он создает экземпляры для цепочек хранения, поэтому вам нужно написать storage(). Я могу изменить его, чтобы он был только одним объектом, но он может стать менее надежным. - person gblazex; 06.07.2010
comment
О, я вижу, да, так что: alert(storage().setItem('names').addItem('Bill').addItem('Tom').getItem('names')); предупреждает Тома, а также localStorage.getItem('names'). Почти идеально, но как я могу вернуть Билла, Тома и т. Д. В том же предупреждении? По сути, вернуть их в массив? Извините, если это выше моего понимания. Я пытаюсь учиться, хотя... Мне нравится этот стиль больше, чем простые функции... - person Oscar Godson; 06.07.2010

Это невозможно.

Если getItem('names') возвращает Bill, вы не можете вызвать для него addItem.
Можно было бы добавить методы addItem и getItem к каждому элементу в хранилище, но это была бы ужасная идея.

person SLaks    schedule 04.07.2010
comment
это возможно (без расширения localStorage). см. мой ответ. Не очень полезный случай, но хорошая демонстрация шаблона декоратора. - person gblazex; 05.07.2010
comment
@galambalazs: использовать его точные звонки невозможно. - person SLaks; 05.07.2010
comment
getItem() разрывает цепочку, это очевидно, но вам не нужно добавлять методы к каждому элементу в хранилище. - person gblazex; 05.07.2010
comment
Нет, нет, но то, что вы пытались сделать, было очень похоже на jQuery в плохом смысле: D - person Jani Hartikainen; 06.07.2010
comment
Как бы вы предложили сделать функцию addItem? если не добавить элемент, это много дополнительной разметки. Я бы предпочел сделать это СУХИМ способом... - person Oscar Godson; 06.07.2010

Проще всего было бы не делать этого вообще :)

Если это не сработает, то есть такие решения, как изменение нативной функции getItem, но это очень плохая идея. Лучшим способом было бы написать оболочку вокруг localStorage, очень похожую на то, что jQuery делает с узлами DOM, и использовать эту оболочку для получения и помещения элементов в локальное хранилище. Оболочка может иметь такой интерфейс, как:

ApplicationStorage
    getItem()
    setItem()
    key()
    removeItem()

Затем определите приемлемые оболочки типов, такие как Array, в ApplicationStorage, которые имеют такие методы, как addItem.

ApplicationStorage.Array
    addItem()

При вызове applicationStorage.getItem("names") вернуть объект ApplicationStorage.Array, содержащий метод addItem, который сделает возможной цепочку.

person Anurag    schedule 04.07.2010

getItem('names').addItem('Bill').getItem('names')

Я в замешательстве, как вы получаете элемент, который не был добавлен???

getItem возвращает объект, содержащий метод addItem, а метод addItem возвращает объект, содержащий метод getItem.

В любом случае, посмотрите следующий учебник. Это не решит полностью вашу проблему, но даст вам представление.

http://guanfenglin.spaces.live.com/blog/cns!4E0822BF6C959B7F!668.entry

person James Lin    schedule 04.07.2010