JavaScript IF оператор булев строг

Задавам режим в скрипт, като предавам "истинско" булево значение на функция. Във функцията прост оператор if проверява дали параметърът е true или false. Понякога го предавам като низ или bool, което винаги е работило, но по някаква причина не е за това:

setMode: function(Setting) {    
    if (Setting) {
        console.log('Enabling mode');
    } else {
        console.log('Disabling mode');
    }
}

Например, когато му предам низ 'false' и регистрирам Setting към конзолата, конзолата казва false, но операторът if смята, че е верен.

Трябва да добавя това в началото на функцията, за да работи:

if (typeof Setting == 'string') { Setting = (Setting == "true"); }

Пример за употреба:

var inverted = $('INPUT[name="Mode"]').prop('checked');
app.setMode(inverted);

и друг:

var mode = localStorage.getItem('Mode');
this.setMode(mode);

Толкова е странно, тъй като съм правил подобни неща от години, но едва сега започва. Може би защото използвам localStorage и .prop?


person Jared    schedule 26.05.2013    source източник
comment
localStorage може да съхранява само низове. Препоръчвам достъпът до LS винаги да бъде обвит в двойка JSON.parse/stringify.   -  person John Dvorak    schedule 26.05.2013
comment
Има ли значение? Изявление if пак ще го види като true или false, ако е низ или булево, но не е в този случай.   -  person Jared    schedule 26.05.2013
comment
Освен това се опитах да използвам квадратче за отметка със същите резултати.   -  person Jared    schedule 26.05.2013


Отговори (3)


Ако се опитате да регистрирате 'false', очевидно е, че конзолата регистрира false (това е низ) и че инструкцията if вижда true, тъй като непразният низ е истинска булева стойност.

Ако искате да проверите дали низът е "true" или "false", трябва да го направите с нормални оператори. Така че можете да добавите този ред в началото на вашата функция:

Setting = (typeof Setting === 'string') ? Setting === "true" : Setting;
person Niccolò Campolungo    schedule 26.05.2013
comment
Това няма да работи с низа 'false'. !!'false' === true - person JAM; 26.05.2013
comment
Вижте моя актуализиран отговор, празните низове са неверни, не-празните са верни за JS. - person Niccolò Campolungo; 26.05.2013
comment
По какво if (!!Setting) се различава от if (Setting), освен добавянето на безполезни бъркотии? - person interjay; 26.05.2013
comment
Различно е да регистрирате Setting или !!Setting, така или иначе сте прав, в този случай не променя нищо, най-добрият начин да го направите е да добавите if (typeof Setting == 'string') { Setting = (Setting == "true"); } - person Niccolò Campolungo; 26.05.2013
comment
Защо трябва да го принуждавам да бъде булево? Не трябва ли изявлението if да го вижда като true или false, защото е вярно или фалшиво? - person Jared; 26.05.2013

За да отговорите на въпроса си относно преобразуването на низ към булево:

ECMA SPEC:

Резултатът [на това преобразуване] е невярно, ако аргументът е празен низ (дължината му е нула); иначе резултатът е верен.

Така че да, ако подадете низа "false", той ще бъде преобразуван в true, което означава, че единствената опция, която имате, е ръчно да проверите за низовете "true" или "false" и да направите преобразуването сами.

Предполага се обаче, че функцията jQuery .prop("checked") връща булева стойност (или undefined, ако свойството не е дефинирано). Така че бих казал, че всъщност трябва да можете да го направите

if (elem.prop("checked"))

като тук.

person basilikum    schedule 26.05.2013

Например, когато му предам низ 'false' и го регистрирам в конзолата, конзолата казва false, но операторът if смята, че е верен.

Изходът на конзолата е объркващ, той прикрива кавичките и регистрира false както за низа "false", така и за булевото false. И все пак, тези две не са еквивалентни, низът не е празен и наистина е верен.

Може би защото използвам localStorage и .prop?

да Свойството .checked връща булево значение и всичко работи добре. За разлика от това, локалното хранилище съхранява само низове и когато подадете булево значение, вие връщате неговата низова стойност. Можете да отмените това, като използвате

var modeStr = localStorage.getItem('Mode');
var mode = JSON.parse(modeStr);
this.setMode(mode);
person Bergi    schedule 26.05.2013