Почему & ldquo; false & rdquo; из локального хранилища & lt; ldquo; true & rdquo; для модели? [Дубликат]

По вопросу «что мне делать с этим» может быть много ответов.

Более «формальный» способ предотвращения таких ошибок при разработке применяя дизайн по контракту в вашем коде. Это означает, что при разработке вы должны установить инварианты класса и / или даже предпосылки для функции и .

Короче говоря, инварианты класса гарантируют, что в вашем классе будут некоторые ограничения, которые не будут нарушены при нормальном использовании (и, следовательно, класс будет not получить в несогласованном состоянии). Предпосылки означают, что данные, данные как входные данные для функции / метода, должны соответствовать установленным ограничениям и никогда не нарушать их, а постулаты означают, что вывод функции / метода должен соответствовать установленным ограничениям снова не нарушая их. Условия контракта никогда не должны нарушаться во время выполнения программы без ошибок, поэтому дизайн по контракту проверяется на практике в режиме отладки, а отключен в выпусках , чтобы максимизировать развитую производительность системы.

Таким образом, вы можете избежать случаев NullReferenceException, которые являются результатом нарушения установленных ограничений. Например, если вы используете свойство объекта X в классе, а затем попытаетесь вызвать один из его методов, а X имеет нулевое значение, то это приведет к NullReferenceException:

public X { get; set; }

public void InvokeX()
{
    X.DoSomething(); // if X value is null, you will get a NullReferenceException
}

Но если вы установите «свойство X никогда не должно иметь нулевого значения» в качестве предпосылки для метода, вы можете предотвратить описанный ранее сценарий:

//Using code contracts:
[ContractInvariantMethod]
protected void ObjectInvariant () 
{
    Contract.Invariant ( X != null );
    //...
}

По этой причине Код Контракт существует для приложений .NET.

В качестве альтернативы дизайн по контракту может быть применен с использованием утверждений .

ОБНОВЛЕНИЕ: Стоит отметить, что этот термин был придуман Бертраном Майером в связи с его дизайном языка программирования Эйфеля .

69
задан Jiew Meng 16 July 2010 в 09:33
поделиться

8 ответов

В реализации Firefox Storage могут храниться только строки, но в 2009 сентябрь W3C изменил проект, чтобы принять любые данные. Реализация (по-прежнему) еще не завершена ( см. Редактировать ниже ).

Итак, в вашем случае логическое преобразование преобразуется в строку.

Что касается того, почему "true" != true, как написано в , описание Equal (==) в MDC *:

Если два операнда не одного типа , JavaScript преобразует операнды, а затем применяет строгое сравнение. Если любой операнд является числом или логическим, операнды, если это возможно, преобразуются в числа; else, если любой операнд является строкой, другой операнд, если возможно, преобразуется в строку.

Обратите внимание, что строка преобразуется в Number вместо Boolean . Поскольку "true", преобразованный в число, является NaN, он не будет равным никому, поэтому возвращается false.

(*: для фактического стандарта см. ECMA-262 & sect; 11.9 .3 «Алгоритм сравнения абстрактного равенства»)


Редактирование: интерфейс setItem был возвращен, чтобы принимать строки только в 2011 1-го сентября , чтобы соответствовать поведению существующих реализаций, так как ни один из поставщиков не заинтересован в поддержке хранения строк. Подробнее см. https://www.w3.org/Bugs/Public/show_bug.cgi?id=12111 .

41
ответ дан kennytm 23 August 2018 в 22:26
поделиться
  • 1
    Если любой из операндов является числом или логическим, операнды преобразуются в числа , если возможно - я полностью этого не осознавал. Я думал, что если бы кто-то был строкой, другой был брошен в строку. Приветствия (+1). – Andy E 16 July 2010 в 10:01
  • 2
    @Andy, проверьте это полезные заметки на тему. – CMS 16 July 2010 в 17:00
  • 3
    @CMS: Спасибо, большое чтение. – Andy E 16 July 2010 в 17:15

Мои решения:

function tytPreGetBool(pre) {
    return localStorage.getItem(pre) == 'true' ? true : false;
}
5
ответ дан Andrei 23 August 2018 в 22:26
поделиться
  • 1
    Почему это занижено? – koppor 6 July 2017 в 14:00
  • 2
    @koppor Возможно потому, что если getItem когда-либо вернет логическое значение, тогда этот метод даст ложные результаты, так как true == 'true' - false. – jox 5 December 2017 в 16:11
  • 3
    .. или обычный localStorage.getItem(pre)==='true' без остального – Blauhirn 10 April 2018 в 11:17

На данный момент все реализации Safari , WebKit, Chorme, Firefox и IE следуют старой версии стандарта WebStorage, где значение элементов хранения может быть только строкой.

Параметр должен был бы использовать JSON parse и stringify метод для serialize и десериализуют данные, как я предположил некоторое время назад в другой вопрос , например:

var value = "true";
JSON.parse(value) === true; // true
59
ответ дан Community 23 August 2018 в 22:26
поделиться
  • 1
    Это, очевидно, будет нарушено, если строка, прошедшая в value, недействительна JSON (например, JSON.parse("a random string")) – Adonis K. Kakoulidis 6 December 2014 в 11:40
  • 2
    True @AdonisK. Но если он использует JSON.stringify при установке всех значений, он может разгрузить ответственность за вывод правильного JSON в библиотеку. И это очень стабильная библиотека. – Colt McCormack 10 February 2015 в 22:18

eval также можно использовать в некоторых случаях.

console.log(eval("true") === true) //true
1
ответ дан deadlock 23 August 2018 в 22:26
поделиться

То, что я обычно делаю, это просто сохранить значение в LocalStore как логическое, а затем получить с помощью метода синтаксического анализа, просто для всех браузеров. Мой метод ниже настроен для моей бизнес-логики. Иногда я мог бы хранить smth как «нет» и все еще нуждаюсь в false взамен

function toBoolean(str) {
    if (typeof str === 'undefined' || str === null) {
        return false;
    } else if (typeof str === 'string') {           
        switch (str.toLowerCase()) {
        case 'false':
        case 'no':
        case '0':
        case "":
            return false;
        default:
            return true;
        }
    } else if (typeof str === 'number') {
        return str !== 0
    }
    else {return true;}
}
0
ответ дан JohnPan 23 August 2018 в 22:26
поделиться

Используйте store.js :

localStorage.setItem('isUser', true)
localStorage.getItem('isUser') === "true" //true
npm i -D store

store.get('isUser')  //true
1
ответ дан Nathan Tuggy 23 August 2018 в 22:26
поделиться

[хотел снять этот комментарий с ответа CMS, но я полагаю, что мне еще не разрешено. : -P]

Вот небольшая функция, которую я использовал для обработки парсинга этой проблемы (функция будет продолжать делать правильную вещь после того, как реализации браузера догонят спецификацию, поэтому не нужно не забудьте изменить код позже):

function parse(type) {
   return typeof type == 'string' ? JSON.parse(type) : type;
}
4
ответ дан oldestlivingboy 23 August 2018 в 22:26
поделиться
  • 1
    Разве это не лишнее по сравнению с JSON.parse? JSON.parse («true») и JSON.parse (true) уже возвращают true, поэтому будут по-прежнему поступать правильно, когда браузеры будут реализовывать логическое localstorage – bscan 22 April 2017 в 22:50

Я не уверен, что LocalStorage может сохранять логические значения, но я могу сказать, что когда вы делаете alert("true" == true);, он никогда не будет оценивать true, потому что вы неявно сравниваете строку с логическим. Поэтому для установки булевых значений вы используете true вместо "true".

1
ответ дан Roman 23 August 2018 в 22:26
поделиться
  • 1
    Что относительно предупреждения («1» = 1)? Javascript - странное (и непоследовательное) beasty. – spender 16 July 2010 в 09:45
  • 2
    @ Энди: Нет, это не так. – kennytm 16 July 2010 в 09:47
  • 3
  • 4
    @Kenny: whoops facepalm , спасибо за исправление :-) Я был замешан из-за того, как булевы отбрасываются в строки. – Andy E 16 July 2010 в 09:51
Другие вопросы по тегам:

Похожие вопросы: