В чем смысл логического объекта?

Я читаю Руководство Mozilla по JavaScript, и я подошел к этому моменту в своем чтении: логический объект. Я не вижу для них одноразового использования. В чем их точка зрения? Почему бы вам не использовать только true и false?

Кстати, я совсем не знаю Java и не боюсь узнавать что-то новое, поэтому я и пытаюсь изучить JavaScript. Я программист PHP, специалист по серверной части, и я хотел бы узнать, как выполнять некоторую работу с интерфейсом, поэтому я читаю Руководство Mozilla JavaScript.


person Mark Tomlin    schedule 26.05.2011    source источник
comment
См. Также Какова цель new Boolean () в Javascript?   -  person Bergi    schedule 17.09.2015


Ответы (9)


Поскольку это (несколько печально) то, как был определен язык - я подозреваю, что изначально это было сделано для повышения производительности / оптимизации; обратите внимание на случай присвоения свойству string ниже. (Java работает аналогично, хотя Scala и Python в значительной степени отвергают это различие).

Обратите внимание, что Boolean - не единственный «тип оболочки». Например, есть еще String и Number.

Из-за этого остается ряд причуд (нижеприведенное может быть в той же степени применимо к Boolean):

typeof("foo") // string
typeof(new String("foo")) // object
"foo" instanceof String // false
new String("foo") instanceof String // true

// result is undefined: a string is a primitive and silently "ate" the assignment
// this also makes it a much cheaper value as it's not a "real" object
x = "f"; x.bar = 42; x.bar

// result is 42: a String is a "real" object with real properties!
// however, this also means that it may have a good bit more overhead
x = new String("f"); x.bar = 42; x.bar

Я знаю, что это не "ответило" на вопрос, а скорее бросило еще немного дров в огонь ;-)

Единственная реальная "ошибка" в противном случае из вышеизложенного состоит в том, что, возможно, new Boolean(false) является истинным значением.

Удачного кодирования.

person Community    schedule 26.05.2011

В дизайне языка JavaScript довольно много запыленных углов, и Boolean - один из них; на практике не используется.

Этот:

var a = [];
alert(a instanceof Array);

скажет вам "правда". Но это:

var b = true;
alert(b instanceof Boolean);

почему-то покажет "ложь".

Короче: забудьте об этом.

person c-smile    schedule 26.05.2011
comment
Это не просто какая-то причина, причина в том, что true примитивен, а Boolean - объект. То же, что и 1 instanceof Number == false - person Qwerty; 13.07.2017

Создание нового логического объекта «в основном» запускает часть кода в операторе, а затем оттуда возвращает истинное логическое значение.

Из тех же документов:

1 var b = new Boolean(false);
2 if (b) // this condition evaluates to true

https://developer.mozilla.org/en/JavaScript/Guide/Statements#if...else_Statement

person DefconRhall    schedule 26.05.2011
comment
Итак, это позволяет мне подключиться к оператору if без явного вызова методов этого объекта, потому что это сделано внутренне? Какой метод я бы подумал над записью, чтобы получить эту функциональность, это конструктор? - person Mark Tomlin; 26.05.2011
comment
Правильный способ получить значение логического объекта - b.valueOf(). if (b) всегда верно для любого объекта, даже if ({}) ... верно. - person Qwerty; 13.07.2017

Возможно, потому, что объекты JavaScript расширяемы в отличие от примитивов? (Я просто догадываюсь, мне никогда не было нужды в Boolean.

person Paul Tomblin    schedule 26.05.2011

Boolean.prototype.bang = function() {
    return !this.valueOf();
}

true.bang(); // false

Все в JavaScript - это объект. Но в то же время у нас есть примитивы. Это действительно сбивает с толку, просто не зацикливайтесь на этом.

person Raynos    schedule 26.05.2011
comment
Это действительно интересно! true instanceof Boolean // false, но расширение объекта Boolean влияет на это. Можете ли вы добавить ссылки для получения дополнительной информации? Это довольно сложно найти. - person Qwerty; 13.07.2017

Из документации:

Не путайте примитивные логические значения true и false с истинными и ложными значениями логического объекта. Любой объект, значение которого не является неопределенным, нулевым, 0, NaN или пустой строкой, включая логический объект, значение которого равно false, оценивается как истинное при передаче в условный оператор.

Представьте себе следующий сценарий:

if(SomeBoolean){...}

будет истинным в сценариях, где SomeBoolean - логический объект.

Наоборот:

if(false){...}

всегда будет ложным

Дополнение для разъяснения.

var someString = new Boolean("MyNonEmptyString")
if(someString) //true
var otherString = new Boolean("")
if(otherString) //false
person Woot4Moo    schedule 26.05.2011
comment
Это кажется аргументом в пользу того, почему вам не следует использовать логический объект, а не почему вы должны это делать. - person Paul Tomblin; 26.05.2011
comment
Мне не нравится этот пример. SomeBoolean всегда будет истинным, если это логический объект или если ему присвоено истинное значение. Обратный случай на самом деле не обратный, он должен быть if (false) всегда будет ложным. - person RobG; 26.05.2011
comment
@RobG для вас я поменял его на ложный и контрапозитивный. - person Woot4Moo; 26.05.2011
comment
Кажется, это контрастирует с другими ответами. Последнее условие, if(otherString), для меня true: jsbin.com/ijixi3 - person Kobi; 26.05.2011
comment
@Kobi мое объявление "" должно переводиться в пустую строку. - person Woot4Moo; 26.05.2011
comment
@ Woot4Moo - Не уверен, что понимаю ... Вы пробовали запустить свой код? Я получаю true на if(otherString) //false. - person Kobi; 26.05.2011
comment
@Kobi нет, я не запускал код, потому что на всех языках, которые я когда-либо использовал, "" равно empty string. Кроме того, по ссылке, которую вы мне предоставили, я отказываюсь переходить, потому что она довольно хорошо открывает для меня XSS. - person Woot4Moo; 26.05.2011
comment
@ Woot4Moo - Конечно, "" - это пустая строка. Я спросил, запускаете ли вы написанный вами код. В любом случае, неважно, но вы ошибаетесь (и имеете нечеткое представление о том, что такое XSS, но это другое дело :)). - person Kobi; 26.05.2011
comment
@Kobi Я даже не собираюсь с вами спорить о том, что такое XSS, а что нет. Жалуйтесь разработчикам JavaScript, если их документация неверна. - person Woot4Moo; 26.05.2011
comment
otherString оценивается как true, поскольку вы фактически приводите объект к логическому значению, что всегда верно для любого объекта. Хотя на самом деле это ложьotherString.valueOf() == false - person Qwerty; 13.07.2017

Вы можете получить истинное или ложное из любого значения с помощью return Boolean(something), но короче написать return !!something, что также приводит к истинному или ложному.

person kennebec    schedule 26.05.2011
comment
Хорошая детализация с принудительным использованием true из false возвращаемого значения с помощью !!. +1, но это не отвечает на мой вопрос. - person Mark Tomlin; 27.05.2011

Я бы согласился с большинством присутствующих здесь людей в том, что в логическом объекте нет особой необходимости, но я хочу указать на пару вещей.

Явное сравнение по-прежнему будет оцениваться как логическое:

var someBool = new Boolean(false);
if (someBool == false)
    alert('Got here'); //Alerts 'Got here'

Из-за этого вы можете вроде расширить его до подкласса и по-прежнему иметь возможность выполнять сравнение, как указано выше:

var classExtension = {
    toYN: function() {
        return this == false ? 'N' : 'Y';
    }
};

function getNewClass(val) {
    var newBool = new Boolean(val);
    jQuery.extend(newBool, classExtension);
    return newBool;
}

var newTest = getNewClass(false);
if (newTest)
    alert('It\'s alive');
if (newTest == false)
    alert('And still a bool');
alert(newTest.toYN());

Это предупредит: «Это живое», «И все же булево» и «N». http://jsfiddle.net/fkJuk/

Но опять же, действительно ли вам это понадобится? Даже если бы вы это сделали, вероятно, было бы лучше просто иметь свой собственный отдельный класс с проверяемым логическим свойством. В конце концов, он, вероятно, здесь для единообразия; у каждого примитива есть прямой доступ к конструктору и прототипу в JavaScript.

person Matt Molnar    schedule 26.05.2011

Возвращаясь к спецификации (ECMA-262.pdf, стр. 151), обратите внимание, что когда Boolean вызывается как функция, а не как конструктор, он выполняет преобразование типов. Таким образом:

var t = 5
  , f = 0

console.log(Boolean(t))  //Prints true
console.log(Boolean(f))  //Prints false

Конечно, будучи объектом JavaScript, вы можете использовать его в качестве прототипа с помощью оператора new, как отмечали другие, но я не вижу причин для этого.

person Tamzin Blake    schedule 26.05.2011