this в объектах

Тема в разделе "JavaScript", создана пользователем Q_BASIC, 20 май 2015.

Модераторы: ZiX
  1. Q_BASIC

    Q_BASIC

    Регистр.:
    30 ноя 2013
    Сообщения:
    380
    Симпатии:
    236
    Здравствуйте :)

    Решил свой класс для localStorage сделать.

    Код:
    Код:
    function supports_html5_storage() {
        try {
            return 'localStorage' in window && window['localStorage'] !== null;
        } catch (e) {
            return false;
        }
    }
    
    if(!supports_html5_storage()){
        var ls = false;
    }else{
        var ls = {
     
            'events': {},
     
            'storage': window.localStorage,
    
            'set': function(key, value){
                return this.storage.setItem(key, value);
            },
     
            'get': function(key){
                return this.storage.getItem(key);
            },
     
            'on': function(key, callback){
                console.log('This in function "ON": ');
                console.log(this); // Тут this это объект ls, как, я думаю, и должно быть
         
                this.events[key] = callback;
            },
     
            'off': function(key){
                this.events.key = function(){};
            },
     
            'callback': function(event){
                try{
                    console.log('This in function "CALLBACK": ');
                    console.log(this); // А тут в this содержится объект window. Почему?
             
                    this.events[event.key]();
                    console.log('Storage event \''+event.key+'\' called');
                } catch (e) {
                    console.log('Storage event \''+event.key+'\' not defined. Error: '+e.message);
                }
            }
    
        };
        if (addEventListener) {
            addEventListener("storage", ls.callback, false);
        } else {
            attachEvent("onstorage", ls.callback);
        }
    }
    
    
    В одной функции this содержит объект ls (сам объект), а в другой уже window.

    Как во втором случае обращаться к "себе"? И почему так происходит?


    В коде искать эти места (там не понятно:(
    Код:
    console.log(this); // Тут this это объект ls, как, я думаю, и должно быть
    console.log(this); // А тут в this содержится объект window. Почему?
    В консоли:
    Код:
    This in function "ON":
    Object {events: Object, storage: Storage, set: function, get: function, on: function…}
    
    Код:
    This in function "CALLBACK":
    Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
    Storage event 'foo' not defined. Error: Cannot read property 'foo' of undefined 
     
    Последнее редактирование: 20 май 2015
  2. ZiX

    ZiX Коддинг, Парсинг

    Moderator
    Регистр.:
    9 июл 2011
    Сообщения:
    1.386
    Симпатии:
    575
    Простите меня, а зачем писать? есть простейший.
    теже яйца только в профиль
    https://github.com/Upstatement/jquery-total-storage/blob/master/jquery.total-storage.js
    Модифицируйте да и всё)
     
  3. Q_BASIC

    Q_BASIC

    Регистр.:
    30 ноя 2013
    Сообщения:
    380
    Симпатии:
    236
    Нее, он не подходит. Всё что там есть, я уже и так сделал.

    Мне этот класс нужен только для общения вкладок браузера, а в том классе этого нет.
     
  4. ZiX

    ZiX Коддинг, Парсинг

    Moderator
    Регистр.:
    9 июл 2011
    Сообщения:
    1.386
    Симпатии:
    575
    Код:
    'callback': function(event){
                var this_mod = this;
                try{
                    console.log('This in function "CALLBACK": ');
                    console.log(this_mod); // А тут в this содержится объект window. Почему?
            
                    this.events[event.key]();
                    console.log('Storage event \''+event.key+'\' called');
                } catch (e) {
                    console.log('Storage event \''+event.key+'\' not defined. Error: '+e.message);
                }
            }
    Попробуйте так, я думаю всё проблема в том, что внутри try, this уже "не тот".
     
  5. Q_BASIC

    Q_BASIC

    Регистр.:
    30 ноя 2013
    Сообщения:
    380
    Симпатии:
    236
    Не помогло, в this_mod содержится объект window
     
  6. ZiX

    ZiX Коддинг, Парсинг

    Moderator
    Регистр.:
    9 июл 2011
    Сообщения:
    1.386
    Симпатии:
    575
    a ls.on() и ls.callback() вызываются в одинаковых условиях? или разных вкладках?
     
  7. Q_BASIC

    Q_BASIC

    Регистр.:
    30 ноя 2013
    Сообщения:
    380
    Симпатии:
    236
    На одной вкладке, разных условиях.

    ls.on() вызывается "в ручную":
    Код:
    ls.on('foo', function(event){
    console.log('Event key: '+event.key);
    });
    А ls.callback вызывается браузером при изменении локального хранилища на всех вкладках, кроме вкладки на которой было создано событие изменения хранилища

    ls.callback вызывается на одной вкладке, а выполняется на других
    Вызов callback:
    Код:
    addEventListener("storage", ls.callback, false);
    attachEvent("onstorage", ls.callback);
     
    Последнее редактирование: 20 май 2015
  8. ZiX

    ZiX Коддинг, Парсинг

    Moderator
    Регистр.:
    9 июл 2011
    Сообщения:
    1.386
    Симпатии:
    575
    я щас в хроме попробовал, только вот так
    Код:
    'callback': function(event){
                try{
                    console.log('This in function "CALLBACK": ');
                    console.log(this); // À òóò â this ñîäåðæèòñÿ îáúåêò window. Ïî÷åìó?
            
                    this.events[event]();
                    console.log('Storage event \''+event+'\' called');
                } catch (e) {
                    console.log('Storage event \''+event+'\' not defined. Error: '+e.message);
                }
            }
    Потом
    Код:
    ls.on('foo', function(event){
    console.log('Event key: '+event.key);
    });
    Потом
    Код:
    ls.callback('foo')
    И всё нормально, всё работает, выдает по this именно ls/
    тестил последним хромом
     
  9. Q_BASIC

    Q_BASIC

    Регистр.:
    30 ноя 2013
    Сообщения:
    380
    Симпатии:
    236
    А ларчик просто открывался...
    Код:
    if (addEventListener) {
            addEventListener("storage", function(event){ls.callback(event)}, false, true);
        } else {
            attachEvent("onstorage", function(event){ls.callback(event)});
        }
    Анонимная функция и всё работает как надо.

    А Вы не правильно вызвали callback. Он сам вызывается браузером.

    На одной вкладке ловим изменение ключа foo:
    Код:
    ls.on('foo', function(event){
    console.log('Event "foo" called!');
    });
    На другой вкладке изменяем foo:
    Код:
    ls.set('foo', 'значение');
    И на первой появится после изменения:
    Код:
    Event "foo" called!'
    Тему можно закрывать
     
  10. ZiX

    ZiX Коддинг, Парсинг

    Moderator
    Регистр.:
    9 июл 2011
    Сообщения:
    1.386
    Симпатии:
    575
    Точно, извиняюсь, необратил внимания.