Как проверить, является ли тип логическим

269

Как я могу проверить, имеет ли тип переменной тип Boolean?

Я имею в виду, есть несколько альтернатив, таких как:

if(jQuery.type(new Boolean()) === jQuery.type(variable))
      //Do something..

Но это не кажется мне симпатичным.

Есть ли более чистый способ добиться этого?

Матиас Цицерон
источник
1
Не trueили falseтипа булева?
Матиас Цицерон
1
Вам не нужно проверять, вы можете сделать это, !!( ... some expression ...)и результат будет логическим.
Каллум Линнингтон
1
Нет: trueи falseявляются примитивами типа boolean. Булевый тип прописной буквы B - это тип обёртки объекта для булевых примитивов.
Pointy
@CallumLinington, который не будет работать для объектов, созданных с помощью логического конструктора :)
Pointy
1
@CallumLinington try: if (new Boolean(false)) alert("hi");- логический объект с заглавными буквами B всегда "правдив", независимо от базового логического значения little-b.
Заостренный

Ответы:

506

Вот для чего typeof. Скобки необязательны, так как это оператор .

if (typeof variable === "boolean"){
  // variable is a boolean
}
Амит Джоки
источник
7
Непонятно, что пытается сделать OP, но булевы объекты с заглавной буквы B передают «объект» в качестве своего типа через typeof.
Заостренный
14
1) typeofэто не функция. 2) Использование тройного оператора === с typeofне обязательно, так как он всегда будет возвращать строку (ага, но, насколько я помню, был другой случай для некоторых очень старых браузеров). 3) typeofи сравнения строк медленные. Не используйте их. Проверьте напрямую с помощью (variable === true || variable === false)(я предлагаю написать функцию).
StanE
6
не typeof(variable) === typeof(true)будет более надежным?
Маркус Юний Брут
2
@TusharNiras nameявляется глобальным свойством окна со специальным геттерным developer.mozilla.org/en-US/docs/Web/API/Window/name
Zach Lysobey
1
@MarcusJuniusBrutus @AmitJoki - это чепуха, нет никакого преимущества в использовании более многословного typeof trueвместо "boolean". Новые версии ECMAScript никогда не будут иметь каких-либо серьезных изменений.
m93a
40

Если вы просто хотите проверить примитивное значение

typeof variable === 'boolean'

Если по какой-то странной причине у вас есть логические значения, созданные с помощью конструктора, это на самом деле не логические значения, а объекты, содержащие примитивное логическое значение, и один из способов проверить как примитивные логические значения, так и объекты, созданные с помощью new Boolean:

function checkBool(bool) {
    return typeof bool === 'boolean' || 
           (typeof bool === 'object' && 
            bool !== null            &&
           typeof bool.valueOf() === 'boolean');
}

adeneo
источник
2
Мне кажется не очень практичным рассматривать булевы примитивы и булевы объекты как одно и то же, потому что я все равно не могу использовать их одинаково.
Феликс Клинг
@FelixKling - мне тоже не кажется очень практичным, но кажется, что OP пытается определить, является ли переменная булевой, даже если она создана с помощью new Boolean(), которая технически не является булевой, но является объектом, но все еще содержит логическое значение.
Adeneo
Я думаю, что ОП просто не знал, что new Boolean()возвращает объект (см. Комментарии к вопросу). Но что угодно :)
Феликс Клинг
@FelixKling - Просто перечитайте вопрос и комментарии, и теперь я вижу, что OP в основном пытается сделать typeof variable === typeof new Boolean()и, вероятно, просто хочет регулярную проверку typeof, но каким-то образом попал в какой-то странный синтаксис jQuery.
Аденео
В зависимости от того, как упругими вы хотите сделать свой код, если boolпары проходили в были бы еще оценить и исключение будет брошено на вызов . Таким образом, я бы изменил эту последнюю строку на следующую: она будет оцениваться только тогда, когда она не равна нулю. nulltypeof bool === 'object'TypeError: Cannot read property 'valueOf' of nulltypeof bool.valueOf()(typeof bool === 'object' && bool && typeof bool.valueOf() === 'boolean');bool
Аль Дасс
35

С чистым JavaScript , вы можете просто использовать typeofи делать что-то вроде typeof falseили, typeof trueи он вернется "boolean"...

Но это не единственный способ сделать это, я создаю функции ниже, чтобы показать различные способы проверки логического значения в JavaScript, а также различные способы сделать это в некоторых новых средах, давайте начнем с этого:

function isBoolean(val) {
   return val === false || val === true;
}

Или однострочный способ ES6 ...

const isBoolean = val => 'boolean' === typeof val;

и назовите это как!

isBoolean(false); //return true

Также в исходном коде Underscore они проверяют это следующим образом (с _. В начале имени функции):

isBoolean = function(obj) {
   return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
};

Также в jQuery вы можете проверить это так:

jQuery.type(true); //return "boolean"

В React , если вы используете propTypes, вы можете проверить значение на логическое, например:

MyComponent.propTypes = {
  children: PropTypes.bool.isRequired
};

Если вы используете TypeScript , вы также можете использовать тип boolean :

let isDone: boolean = false;

Также еще один способ сделать это, например, преобразовать значение в логическое и посмотреть, точно ли оно все еще, что-то вроде:

const isBoolean = val => !!val === val;

или как:

const isBoolean = val => Boolean(val) === val;

и позвони!

isBoolean(false); //return true

Не рекомендуется использовать какой-либо фреймворк для этого, так как это действительно простая проверка в JavaScript.

Алиреза
источник
Не согласен: new Boolean(true) === new Boolean(true)должен возвращать false (поскольку ссылки разные). Вот почему isBoolean(new Boolean(true))он скажет ложь, в то время как он должен быть правдой ( new Boolean(true)имеет тип boolean ).
AlexMelw
17

Есть три «ванильных» способа проверить это с или без jQuery.

  1. Сначала нужно принудительно выполнить булеву оценку, а затем проверить, равно ли оно исходному значению:

    function isBoolean( n ) {
        return !!n === n;
    }
    
  2. Делаем простую typeofпроверку:

    function isBoolean( n ) {
        return typeof n === 'boolean';
    }
    
  3. Выполнение полностью излишнего и ненужного создания экземпляра обертки класса в примитиве:

    function isBoolean( n ) {
        return n instanceof Boolean;
    }
    

Третий вернется, только true если вы создадите new Booleanкласс и передадите его.

Чтобы проработать приведение примитивов (как показано в # 1), все типы примитивов можно проверить следующим образом:

  • Boolean:

    function isBoolean( n ) {
        return !!n === n;
    }
    
  • Number:

    function isNumber( n ) {
        return +n === n;
    }
    
  • String:

    function isString( n ) {
        return ''+n === n;
    }
    
iSkore
источник
Почему приведение типа является «наиболее оптимальным»? Это быстрее или более читабельно, чем typeof? Я очень сомневаюсь в этом.
m93a
Таким образом, в теории, приведение значения к логическому значению делает 1 приведение + 2 сравнения + 1 сравнение. Первые два сравнения выполняются на этапах принуждения, а последнее сравнение относится к первой позиции (которая теперь является примитивной). Выполнение typeofтакже 1 принуждение, но typeofметод делает несколько сборщиков и сравнений внутри + 1 сравнения в самом конце. Вот ссылка на V8 дляtypeof
iSkore
1
В конце концов, любой метод чертовски быстр, разница в наносекундах настолько мала, что было бы трудно даже проверить, что было быстрее. Вот два JSPerf's. Один говорит !!быстрее, другой говорит Booleanбыстрее. Просто ссылка на то, насколько мала дельта между тестами. Булевы проверки бывают быстрыми. jsperf.com/bool-not-not jsperf.com/bool-vs-doublenot
iSkore
Я согласен с тем, что разница не поддается измерению и в таком случае читабельности должны AFAIK всегда идти в первую очередь. Таким образом, стандартное и приемлемое typeof val === "boolean"является оптимальным.
M93A
1
Да, я согласен с этим. Читаемость важна. Операторы не так читабельны - будут обновлены
iSkore
16

Вы можете использовать чистый Javascript для достижения этой цели:

var test = true;
if (typeof test === 'boolean')
   console.log('test is a boolean!');
Morry
источник
7

Если вы хотите, чтобы ваша функция также могла проверять логические объекты, самое эффективное решение должно быть:

function isBoolean(val) {
  return val === false || val === true || val instanceof Boolean;
}
Виллем Франко
источник
instanceof Boolean не объявлен для меня.
Дуди
3

Самый надежный способ проверить тип переменной в JavaScript заключается в следующем :

var toType = function(obj) {
  return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
toType(new Boolean(true)) // returns "boolean"
toType(true); // returns "boolean"

Причина этого усложнения в том, что typeof trueвозвращается, "boolean"а typeof new Boolean(true)возвращается "object".

Владимир Фролов
источник
Зачем вам возвращать, "boolean"если значение действительно является объектом? Это не кажется мне очень практичным. В любом случае с булевыми объектами нужно обращаться иначе, чем с булевыми примитивами.
Феликс Клинг
1
Код не чистый, красивый или чистый. Обратите внимание, что ФП требует «более чистого способа добиться этого».
Спенсер Вечорек
Я согласен, что код не является чистым или красивым, но AFAIK не имеет симпатичного и в то же время надежного варианта в случае, если на сцене присутствуют как логические примитивы, так и логические объекты.
Владимир Фролов
Это кажется серьезным излишним решением сделать что-то, что можно сделать изначально.
brandonscript
3

Я бы пошел с Lodash: isBoolean проверяет, является ли передаваемая переменная примитивным логическим или логическим объектом-оболочкой, и поэтому учитывает все случаи.

Маркус Юний Брут
источник
1

Вы можете создать функцию, которая проверяет typeofаргумент.

function isBoolean(value) {
  return typeof value === "boolean";
}
Мохсен Кадура
источник
1

Иногда нам нужен единственный способ проверить это. typeof не работает на дату и т. д. Так что я сделал это легко

Date.prototype.getType() { return "date"; }

Кроме того, для Number, String, и Booleanт.д. , мы часто должны проверить тип в одном пути ...

Имам канкоро
источник
1

Создание таких функций, как isBooleanoneliner, typeof v === "boolean"кажется очень неудобным в долгосрочной перспективе. Я удивлен, что почти все предлагают создать свою собственную функцию. Кажется, это тот же рак, что и расширение прототипов.

  • вам нужно воссоздать их в каждом проекте, в котором вы участвуете
  • у других разработчиков могут быть другие привычки, или они должны проверить источник вашей функции, чтобы узнать, какое использование чека вы используете, чтобы узнать, что является слабым местом вашего чека.
  • вы будете разочарованы, когда попытаетесь написать один вкладыш в консоли на сайте, который не принадлежит вашему проекту

просто запомни typeof v === "boolean"и все. Добавьте шаблон в вашу IDE, чтобы иметь возможность поместить его с помощью трехбуквенного ярлыка и быть счастливым.

Камил Ожеховский
источник
1
Кстати, если производительность очень важна, то наличие функции для проверки логического значения заняло в моих тестах на 10% больше времени, чем встроенное (цикл for 100000000x) на Node.js. Но худший вариант был v === true || v === false, который делает 2 проверки в случае false. Ранжирование: (1 - оба практически одинаковы) typeof v === 'booleanи typeof v === typeof true, (2) isBoolean(v), (3) v === true || v === false.
августа
Я не согласен с этим от всего сердца. Именно поэтому разные привычки: как часто я сталкивался с ошибками, потому что все проверяли вещи по-разному? Если у вас есть одно место для проверки логического значения, это намного предпочтительнее IMO для проверок другого стиля по всей базе кода. Также намного проще последовательно изменять поведение такой функции.
Лукас Манцке
1
if(['true', 'yes', '1'].includes(single_value)) {
    return  true;   
}
else if(['false', 'no', '0'].includes(single_value)) {
    return  false;  
}

если у вас есть строка

Денвер
источник
1
  • Самые читаемые: val === false || val === true.
  • Также читаем: typeof variable == typeof true.
  • Самый короткий, но не читаемый вообще !!val === val.

    Объяснение:

    • [!!] Двойной восклицательный знак преобразует значение в логическое значение.
    • [===] Тройное равенство проверяет строгое равенство: и тип (Boolean), и значение должны быть одинаковыми.
    • Если исходное значение не является логическим, оно не пройдет тест на тройное равенство. Если это булева переменная, она пройдет тест тройного равенства (как с типом, так и со значением).

    тесты:

    • !! 5 === 5 // false
    • !! 'test' === 'test' // false
    • let val = новая дата (); !! val === val // false
    • !! верно === правда // правда
    • !! false === false // true
TechWisdom
источник
0

В nodejs с помощью node-boolify мы можем использовать isBoolean ();

        var isBoolean = require('node-boolify').isBoolean;
        isBoolean(true); //true
        isBoolean('true'); //true
        isBoolean('TRUE'); //false
        isBoolean(1); //true
        isBoolean(2); //false
        isBoolean(false); //true
        isBoolean('false'); //true
        isBoolean('FALSE'); //false
        isBoolean(0); //true
        isBoolean(null); //false
        isBoolean(undefined); //false
        isBoolean(); //false
        isBoolean(''); //false
Ратан Удай Кумар
источник
Возвращает ли логическое значение true только в том случае, если значение является логическим значением
Ратан Удай Кумар,
0

Еще одно решение с функцией стрелки es2015

const isBoolean = val => typeof val === 'boolean';
Gor
источник