Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Приведение пустого массива к булеву типу


Автор: Dima 2015 16.9.2010, 15:33
В общем обнаружил в замечательном языке JavaScript вещь, которая наверняка уж должна быть баяном...

Итак имеем

Код

var arr = [];
var bool = (arr  == true); // false
bool = (!arr ) // false!

// Итого...
bool = (arr  == !arr) // да, совершенно верно - true!!!

Автор: ksnk 16.9.2010, 15:56
Dima 2015, не очень удивительно, если представлять себе правила автоматического http://wdh.suncloud.ru/js03.htm
Цитата

3.3.2. Преобразование типов
JavaScript — слаботипизированный язык. Это означает, что в декларации переменной мы не указываем ее тип и в дальнейшем можем присваивать ей значения любых типов. Исполняющая система JavaScript сама выполняет автоматическое преобразование типов данных по мере необходимости. Для явного преобразования типов используются методы Boolean, Number, Object и String.
Преобразования типов происходят по следующим правилам.
3.3.2.1. Преобразование к логическому типу
Исходный тип    Результат
Undefined    false
Null              false
Boolean      без изменений
Number      false, если аргумент равен +0, -0 или NaN; true в остальных случаях
String         false, если аргумент — пустая строка; true в остальных случаях
Object        true



Добавлено через 3 минуты и 1 секунду
Хотя результат последнего равенства был несколько неожиданн. видимо, если в операции сравнения участвует объект и примитивный тип, то производится приведение к примитивному типу.

Автор: Dima 2015 16.9.2010, 16:01
ksnk, я в курсе всего этого, но тут нет как раз ни слова о конкретно этом примере. В данном случае оба раза приводится один и тот же тип - массив к одному и тому же типу - булеву. И оба раза по-разному.

Добавлено через 3 минуты и 14 секунд
Цитата

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


Да не только последнего, последнее это чтобы скажем так показать наглядно. Меня больше 2е смущает, какого черта ![] трактуется как false, при том что сам [] тоже трактуется как false?

Добавлено через 5 минут и 27 секунд
В пыхе проверил, в пыхе не так, в пыхе отрицание к пустому массиву истину дает, что в общем то и следует ожидать.

Код

$a = array();

var_dump(!$a);         // true
var_dump($a == false); // true
var_dump($a == !$a);   // false

Автор: ksnk 16.9.2010, 16:47
Это только в пыхе пустой массив - false  smile уникальная пыховская фича!

Забавно! Я не смог найти подходящий(логичный) алгоритм преобразования типов во втором случае
Код

var arr = [];
alert(['arr  == true',arr  == true,true == arr ,arr  == Object(true), Boolean(arr)==true,
'\n',typeof(true),typeof(arr),typeof(!arr),
'\narr  == !arr',arr  == !arr, !arr==arr, arr  == Object(!arr), Boolean(arr)  ==!arr, arr  == Boolean(!arr)])


Цитата

arr == true, false, false, false, true,
, boolean, object, boolean,
arr == ! arr, true, true, false, false, true


отсюда получается, что для arr==true выполняется преобразование true к объекту. То есть логично предположить, при разнице типов тип второго операнда насильно приводится к объектному типу.

Для второго случая какбы совсем не так просто. Если тупо преобразовать !arr к объекту счастья так и не получаем :( счастье получаем в случае ПОВТОРНОГО преобразования !arr к логическому. Хотя какбы typeof нас заверяет, что тип и так логический...

В общем резюме - не сравнивайте объекты между собой , может получится конфуз  smile 

Автор: Dima 2015 16.9.2010, 17:06
Нет это все понятно, и понятно что программисту который пишет такие сравнения должны быть оторваны руки (вот я себе и оторвал вчера), но сам факт того что в языке конструкция а == !а может вернуть истину, забавна. В прочем в плюсах такое запросто можно сделать, если соответственно переопределить операции сравнения и отрицания, другое дело что это с точки зрения теорвера дико смотрится.

Какова вероятность завтра выйдя на Невский встретить динозавра? - 0,5 - либо встречу, либо не встречу.

Автор: Deepthroat 16.9.2010, 18:15
Цитата

То есть логично предположить, при разнице типов тип второго операнда насильно приводится к объектному типу.

Не правильно. При сравнении объектов, они приводятся к числам или строкам при помощи методов valueOf() и toString().

В примере выше все получается по правилам. Сперва исполняется оператор "!". При применении его к нелогическому типу, возвращается false в случае, если переменная может быть приведена к значению true. Элементарная проверка new Boolean(arr) показывает, что arr и преобразуется в true. Соответственно, !arr дает false.

Дальше, при сравнении объекта с логической переменной, массив преобразуется при помощи метода .toString(). Так как массив пустой, то и преобразуется он в пустую строку. А пустая строка, при преобразовании к логическому значению, дает false. Вот и получаем, false == false.

Можете посмотреть, как изменится результат, если arr объявить так: var arr = [1]. При преобразовании в строку, это уже будет строка '1', не пустая, которая при приведении к логическому типу даст true. Получится true == false с соответствующим результатом.

Автор: Dima 2015 17.9.2010, 16:53
Deepthroat, разложил по полочкам, спасибо smile

Но сам факт забавен, что конструкция a == !a выдает истину...

Автор: magelan 18.9.2010, 01:58
Ребята из Netscape видать хорошо пыхнули, перед тем как создать нетипизированный клон си.
Прикольно что контору съели, а дитятко живо.

Автор: ksnk 18.9.2010, 11:37
...


Автор: magelan 18.9.2010, 21:51
Я как то про пхп даже не думал, когда писал. неужели JS не тянет на клон си?

Автор: ksnk 18.9.2010, 22:03
magelan, чего-то я торможу smile Про php вот, с чего-то вспомнил...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)