Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 25.12.2016, 04:06
Новичок на форуме
Отправить личное сообщение для inpost Посмотреть профиль Найти все сообщения от inpost
 
Регистрация: 11.11.2013
Сообщений: 1

Undefined внутри for-in перебора без hasOwnProperty
Всем привет.
Что-то не могу разобраться в том, как работает перебор объекта. Вот код:
if (typeof localStorage === 'object') {
	Storage.prototype.getFullSize = function() {
		var tempLen = 0;
		for(var x in localStorage) {
			tempLen = parseFloat(tempLen) + parseFloat((localStorage[x].length * 2)/1024/1024);
		}
		return tempLen;
	}
}


Ругается на localStorage[x].length, код ошибки: Unable to get property 'length' of undefined or null reference . Эмулировать подобную ошибку не получается, она проявляется в некоторых браузерах, вот один из них: Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; Touch; MATBJS; rv:11.0) like Gecko (IE 11).

Я встречал написание кода из документации с использованием hasOwnProperty:
for (var prop in obj) {
    if(!obj.hasOwnProperty(prop)) continue;
    alert(prop + " = " + obj[prop]);
}


Гуглить пробовал, но не могу найти объяснения, зачем это надо и поможет ли это в данном случае. Почему элемент объекта может быть равен undefined или null ? localStorage.setItem('a',null); пробовал, ошибку в моих браузерах не кидает, включая IE 11.

Подскажите почему происходит в редких браузерах подобная ошибка и как с ней бороться? И второй вопрос, для чего в таких случаях пишется hasOwnProperty, неужели доступа может не быть?
Ответить с цитированием
  #2 (permalink)  
Старый 25.12.2016, 06:14
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Метод Object.prototype.hasOwnProperty используется, чтобы определить есть ли у объекта своё собственное, а не унаследованное свойство.

for(var property in object) {} не делает различия между свойствами объекта и его прототипа, перечисляет только перечислимые свойства.

Ошибка, точней не то поведение, появляется во всех браузерах. Вы добавляете в Storage.prototype метод getFullSize, но не указываете, что оно не должно быть перечислимым.

if(typeof localStorage === "object") {
    // добавленный метод
    Storage.prototype.getFullSize = function() {};

    var items = [];

    // засчитано в localStore
    for(var property in localStorage) {
        items.push(property);
    }

    alert(items.join(", "));
}


if(typeof localStorage === "object") {
    // тот же самый пример, но объявляем метод неперечислимым
    Object.defineProperty(Storage.prototype, "getFullSize", {
        value: function() {},
        enumerable: false,
        configurable: true
    });

    var items = [];

    // не засчитано в localStore
    for(var property in localStorage) {
        items.push(property);
    }

    alert(items.join(", "));
}


Но например Модзилла считает свойства из Storage.prototype за перечислимые, поэтому необходима проверка на то, что свойство является собственным(что гарантирует, что ключ именно из локального хранилища). Вот здесь и нужен hasOwnProperty

if(typeof localStorage === "object") {
    // тот же самый пример, но объявляем метод неперечислимым
    Object.defineProperty(Storage.prototype, "getFullSize", {
        value: function() {},
        enumerable: false,
        configurable: true
    });

    var items = [];

    for(var property in localStorage) {
        if(localStorage.hasOwnProperty(property)) {
            
            items.push(property);
        }
    }

    alert(items.join(", "));
}


Ну, а также существует метод Object.keys, который позволяет получить свои собственные имена свойств объекта
if(typeof localStorage === "object") {
    var items = [];

    Object.keys(localStorage).forEach(function(key) {
        items.push(key);
    });

    alert(items.join(", "));
}

Последний раз редактировалось Malleys, 25.12.2016 в 07:15. Причина: добавил { configurable: true }
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Новый контент без перезагрузки внутри кнопки Wolverline Общие вопросы Javascript 1 06.01.2015 19:41