Какие выражения вернут непустой список
Перейти к содержимому

Какие выражения вернут непустой список

Какие выражения вернут непустой список

Скачай курс
в приложении

Перейти в приложение
Открыть мобильную версию сайта

© 2013 — 2023. Stepik

Наши условия использования и конфиденциальности

Get it on Google Play

Public user contributions licensed under cc-wiki license with attribution required

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

Рекомендуем хостинг TIMEWEB

Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

По статье задано0 вопрос(ов)
Подписка на обсуждение 4
Подписка на раздел 73

Вам это нравится? Поделитесь в социальных сетях!

Анатолий Жучков

  • Анатолий Жучков
  • #
  • 13 апреля 2020 г. 19:25
#empty list list_1 = [] #ноль, пустой кортеж, пустой список, пустая строка принимаются как False if not list_1: print('yes! the list is empty.')
  • Ильнур Гайфутдинов
  • #
  • 14 апреля 2020 г. 11:12
  • (ред.)

Автор, очень плохой совет, не делайте так никогда.

делайте как написал Анатолий Жучков, в коментариях

Said Py

  • Said Py → Анатолий Жучков
  • #
  • 15 апреля 2020 г. 6:16

thanks
but if i wanna to check if list is exists how can i do that?

Evgenii Legotckoi

  • Evgenii Legotckoi → Said Py
  • #
  • 15 апреля 2020 г. 13:11

It works similar. If list not exists, then list is None

if list_1: print('yes! the list is not None')

Therefore the following code is right

 
list_1 = None if not list_1: print('the list is empty or None')

Evgenii Legotckoi

  • Evgenii Legotckoi → Said Py
  • #
  • 15 апреля 2020 г. 13:16

I am admin of this site, and I want ask you add special separator in your articles, like this

This is special separator, which separate preview part from main part of article. Please, use it in articles (notes) on this site.

I think you saw some changes in articles after first publication. Just I made moderation and some cleaning of article for improvement of content.

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь

Последние комментарии
gr104712 ноября 2023 г. 10:35

Qt/C++ - Урок 035. Скачивание файла по HTTP с помощью QNetworkAccessManager Добрый день. Изучаю Qt на ваших уроках. Всё нормально работает на Linux. А под Win один раз запустилось, а сейчас вместо данных сайта получается ошибк "Unable to write". Куда копать, ума не…

Damir2 ноября 2023 г. 3:41

Павел Дорофеев

Павел Дорофеев28 октября 2023 г. 14:48

Как написать свой QTableView Итак начинаем писать свои виджеты на основе QAbstractItemView. А что так можно было?

mihamuz15 октября 2023 г. 13:28

Evgenii Legotckoi

Evgenii Legotckoi15 октября 2023 г. 8:47

Выпуск Qt Visual Studio Tools 2.3.1 Добрый день. Нет, не подскажу. Не пользуюсь Visual Studio для проектов на Qt.

Сейчас обсуждают на форуме

Evgenii Legotckoi

Evgenii Legotckoi19 ноября 2023 г. 8:14

CKEditor 5 и подсветка синтаксиса. Добрый день. Я устал разбираться с CKEditor и просто перешёл на использование самописного markdown редактора.

Михаил Лебедев24 октября 2023 г. 3:51
Разные иконки в QTreeView для раскрытых и свернутых веток Решено. через setData в модели.

Виктор Калесников

Виктор Калесников20 октября 2023 г. 4:29

Контакты Android делал в далеком 2017г поэтому особенно ничего не подскажу. Это основные методы получения данных с андроида используя Qt. Там еще какоето колдунство с манифестом. Андроидом давно не занимаюс…

mihamuz18 октября 2023 г. 14:03

Скачать Qt 6 Сработал следующий алгоритм. Инстолятор скачал используя это https://freevpnplanet.com/ru/ как расширение браузера. Потом установил это https://freevpnplanet.com/ru/ же на ПК и через инстолятор …

IscanderChe

IscanderChe17 сентября 2023 г. 9:24

Интернационализация строк в QMessageBox Странная картина. Сделал минимально работающий пример - всё работает. Попробую на другой операционке. Может, дело в этом.

Логические операторы

Здесь мы рассмотрим первые пять, операторы ?? и ??= будут в следующей статье.

Несмотря на своё название, данные операторы могут применяться к значениям любых типов. Полученные результаты также могут иметь различный тип.

Давайте рассмотрим их подробнее.

|| (ИЛИ)

Оператор «ИЛИ» выглядит как двойной символ вертикальной черты:

result = a || b;

Традиционно в программировании ИЛИ предназначено только для манипулирования булевыми значениями: в случае, если какой-либо из аргументов true , он вернёт true , в противоположной ситуации возвращается false .

В JavaScript, как мы увидим далее, этот оператор работает несколько иным образом. Но давайте сперва посмотрим, что происходит с булевыми значениями.

Существует всего четыре возможные логические комбинации:

alert( true || true ); // true alert( false || true ); // true alert( true || false ); // true alert( false || false ); // false

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

Если значение не логического типа, то оно к нему приводится в целях вычислений.

Например, число 1 будет воспринято как true , а 0 – как false :

if (1 || 0) < // работает как if( true || false ) alert( 'истинно!' ); >

Обычно оператор || используется в if для проверки истинности любого из заданных условий.

let hour = 9; if (hour < 10 || hour >18)

Можно передать и больше условий:

let hour = 12; let isWeekend = true; if (hour < 10 || hour >18 || isWeekend) < alert( 'Офис закрыт.' ); // это выходной >

ИЛИ "||" находит первое истинное значение

Описанная выше логика соответствует традиционной. Теперь давайте поработаем с «дополнительными» возможностями JavaScript.

Расширенный алгоритм работает следующим образом.

При выполнении ИЛИ || с несколькими значениями:

result = value1 || value2 || value3;

Оператор || выполняет следующие действия:

  • Вычисляет операнды слева направо.
  • Каждый операнд конвертирует в логическое значение. Если результат true , останавливается и возвращает исходное значение этого операнда.
  • Если все операнды являются ложными ( false ), возвращает последний из них.

Значение возвращается в исходном виде, без преобразования.

Другими словами, цепочка ИЛИ || возвращает первое истинное значение или последнее, если такое значение не найдено.

alert( 1 || 0 ); // 1 (1 - истинное значение) alert( true || 'какая-то строка' ); // true alert( null || 1 ); // 1 (первое истинное значение) alert( null || 0 || 1 ); // 1 (первое истинное значение) alert( undefined || null || 0 ); // 0 (поскольку все ложно, возвращается последнее значение)

Это делает возможным более интересное применение оператора по сравнению с «чистым, традиционным, только булевым ИЛИ».

    Получение первого истинного значения из списка переменных или выражений. Например, у нас есть переменные firstName , lastName и nickName , все они необязательные (т.е. они могут быть неопределенными или иметь ложные значения). Давайте воспользуемся оператором ИЛИ || , чтобы выбрать ту переменную, в которой есть данные, и показать её (или «Аноним», если ни в одной переменной данных нет):

let firstName = ""; let lastName = ""; let nickName = "Суперкодер"; alert( firstName || lastName || nickName || "Аноним"); // Суперкодер

Неявное преобразование типов в JavaScript. Сколько будет !+[]+[]+![]?

Приведение типов — это процесс преобразования значений из одного типа в другой (например — строки в число, объекта — в логическое значение, и так далее). Любой тип в JavaScript, идёт ли речь о примитивном типе, или об объекте, может быть преобразован в другой тип. Напомним, что примитивными типами данных в JS являются Number , String , Boolean , Null , Undefined . К этому списку в ES6 добавился тип Symbol , который ведёт себя совсем не так, как другие типы. Явное приведение типов — процесс простой и понятный, но всё меняется, когда дело доходит до неявного приведения типов. Тут то, что происходит в JavaScript, некоторые считают странным или нелогичным, хотя, конечно, если заглянуть в стандарты, становится понятно, что все эти «странности» являются особенностями языка. Как бы там ни было, любому JS-разработчику периодически приходится сталкиваться с неявным приведением типов, к тому же, каверзные вопросы о приведении типов вполне могут встретиться на собеседовании.

image

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

Проверь себя

Вот список интересных выражений, о которых мы только что говорили:

true + false 12 / "6" "number" + 15 + 3 15 + 3 + "number" [1] > null "foo" + + "bar" 'true' == true false == 'false' null == '' !!"false" == !!"true" [‘x’] == ‘x’ [] + null + 1 0 || "0" && <> [1,2,3] == [1,2,3] <>+[]+<>+[1] !+[]+[]+![] new Date(0) - 0 new Date(0) + 0

Тут полно такого, что выглядит более чем странно, но без проблем работает в JS, задействуя неявное приведение типов. В подавляющем большинстве случаев неявного приведения типов в JS лучше всего избегать. Рассматривайте этот список как упражнение для проверки ваших знаний о том, как работает приведение типов в JavaScript. Если же тут для вас ничего нового не нашлось — загляните на wtfjs.com.

JavaScript полон странностей

Вот страница с таблицей, в которой показаны особенности поведения оператора нестрогого равенства в JavaScript, == , при сравнении значений разных типов. Неявное преобразование типов, выполняемое оператором == , делает эту таблицу гораздо менее понятной и логичной, чем, скажем, таблица для оператора строгого равенства, === , ссылку на которую можно найти на вышеупомянутой странице. Заучить таблицу сравнений для оператора == практически невозможно. Но запоминать всё это и не нужно — достаточно освоить принципы преобразования типов, применяемые в JavaScript.

Неявное преобразование типов и явное преобразование типов

Преобразование типов может быть явным и неявным. Когда разработчик выражает намерение сконвертировать значение одного типа в значение другого типа, записывая это соответствующим образом в коде, скажем, в виде Number(value) , это называется явным приведением типов (или явным преобразованием типов).

Так как JavaScript — это язык со слабой типизацией, значения могут быть конвертированы между различными типами автоматически. Это называют неявным приведением типов. Обычно такое происходит, когда в выражениях используют значения различных типов, вроде 1 == null , 2/’5' , null + new Date() . Неявное преобразование типов может быть вызвано и контекстом выражения, вроде if (value) , где value неявно приводится к логическому типу данных.

Существует оператор, который не вызывает неявного преобразование типов — это оператор строгого равенства, === . Оператор нестрогого равенства, == , с другой стороны, выполняет и операцию сравнения, и, если нужно, выполняет неявное преобразование типов.

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

Три вида преобразования типов

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

  • В строку ( String )
  • В логическое значение ( Boolean )
  • В число ( Number )

Примитивные типы данных

▍Преобразование к типу String

Для того чтобы явно преобразовать значение в строку, можно воспользоваться функцией String() . Неявное преобразование вызывает использование обычного оператора сложения, + , с двумя операндами, если один из них является строкой:

String(123) // явное преобразование 123 + '' // неявное преобразование

Все примитивные типы преобразуются в строки вполне естественным и ожидаемым образом:

String(123) // '123' String(-12.3) // '-12.3' String(null) // 'null' String(undefined) // 'undefined' String(true) // 'true' String(false) // 'false'

В случае с типом Symbol дело несколько усложняется, так как значения этого типа можно преобразовать к строковому типу только явно. Здесь можно почитать подробности о правилах преобразования типа Symbol.

String(Symbol('my symbol')) // 'Symbol(my symbol)' '' + Symbol('my symbol') // ошибка TypeError

▍Преобразование к типу Boolean

Для того, чтобы явно преобразовать значение к логическому типу, используют функцию Boolean() . Неявное преобразование происходит в логическом контексте, или вызывается логическими операторами ( || && ! ).

Boolean(2) // явное преобразование if (2) < . >// неявное преобразование в логическом контексте !!2 // неявное преобразование логическим оператором 2 || 'hello' // неявное преобразование логическим оператором

Обратите внимание на то, что операторы, вроде || и && выполняют преобразование значений к логическому типу для внутренних целей, а возвращают значения исходных операндов, даже если они не являются логическими.

// это выражение возвращает число 123, а не true // 'hello' и 123 неявно преобразуются к логическому типу при работе оператора && для вычисления значения выражения let x = 'hello' && 123; // x === 123

Так как при приведении значения к логическому типу возможны лишь два результата — true или false , легче всего освоить этот вид преобразований, запомнив те выражения, которые выдают false :

Boolean('') // false Boolean(0) // false Boolean(-0) // false Boolean(NaN) // false Boolean(null) // false Boolean(undefined) // false Boolean(false) // false

Любое значение, не входящее в этот список, преобразуется в true , включая объекты, функции, массивы, даты, а также типы, определённые пользователем. Значения типа Symbol также преобразуются в true . Пустые объекты и пустые массивы тоже преобразуются в true :

Boolean(<>) // true Boolean([]) // true Boolean(Symbol()) // true !!Symbol() // true Boolean(function() <>) // true

▍Преобразование к типу Number

Явное преобразование к числовому типу выполняется с помощью функции Number() — то есть по тому же принципу, который используется для типов Boolean и String .

Неявное приведение значения к числовому типу — тема более сложная, так как оно применяется, пожалуй, чаще чем преобразование в строку или в логическое значение. А именно, преобразование к типу Number выполняют следующие операторы:

  • Операторы сравнения ( > , < , = ).
  • Побитовые операторы ( | , & , ^ , ~ ).
  • Арифметические операторы ( - , + , * , / , % ). Обратите внимание на то, что оператор + с двумя операндами не вызывает неявное преобразование к числовому типу, если хотя бы один оператор является строкой.
  • Унарный оператор + .
  • Оператор нестрогого равенства == (а также != ). Обратите внимание на то, что оператор == не производит неявного преобразования в число, если оба операнда являются строками.
Number('123') // явное преобразование +'123' // неявное преобразование 123 != '456' // неявное преобразование 4 > '5' // неявное преобразование 5/null // неявное преобразование true | 0 // неявное преобразование

Вот как в числа преобразуются примитивные значения:

Number(null) // 0 Number(undefined) // NaN Number(true) // 1 Number(false) // 0 Number(" 12 ") // 12 Number("-12.34") // -12.34 Number("\n") // 0 Number(" 12s ") // NaN Number(123) // 123

При преобразовании строк в числа система сначала обрезает пробелы, а также символы \n и \t , находящиеся в начале или в конце строки, и возвращает NaN , если полученная строка не является действительным числом. Если строка пуста — возвращается 0 .

Значения null и undefined обрабатываются иначе: null преобразуется в 0 , в то время как undefined превращается в NaN .

Значения типа Symbol не могут быть преобразованы в число ни явно, ни неявно. Более того, при попытке такого преобразования выдаётся ошибка TypeError . Можно было бы ожидать, что подобное вызовет преобразование значения типа Symbol в NaN , как это происходит с undefined , но этого не происходит. Подробности о правилах преобразования значений типа Symbol вы можете найти на MDN.

Number(Symbol('my symbol')) // Ошибка TypeError +Symbol('123') // Ошибка TypeError

Вот два особых правила, которые стоит запомнить:

При применении оператора == к null или undefined преобразования в число не производится. Значение null равно только null или undefined и не равно ничему больше.

null == 0 // false, null не преобразуется в 0 null == null // true undefined == undefined // true null == undefined // true

Значение NaN не равно ничему, включая себя. В следующем примере, если значение не равно самому себе, значит мы имеем дело с NaN

if (value !== value)

Преобразование типов для объектов

Итак, мы рассмотрели преобразование типов для примитивных значений. Тут всё довольно просто. Когда же дело доходит до объектов, и система встречает выражения вроде [1] + [2,3] , сначала ей нужно преобразовать объект в примитивное значение, которое затем преобразуется в итоговой тип. При работе с объектами, напомним, также существует всего три направления преобразований: в число, в строку, и в логическое значение.

Самое простое — это преобразование в логическое значение: любое значение, не являющееся примитивом, всегда неявно конвертируется в true , это справедливо и для пустых объектов и массивов.

Объекты преобразуются в примитивные значения с использованием внутреннего метода [[ToPrimitive]] , который ответственен и за преобразование в числовой тип, и за преобразование в строку.

Вот псевдо-реализация метода [[ToPrimitive]] :

function ToPrimitive(input, preferredType) < switch (preferredType)< case Number: return toNumber(input); break; case String: return toString(input); break default: return toNumber(input); >function isPrimitive(value) < return value !== Object(value); >function toString() < if (isPrimitive(input.toString())) return input.toString(); if (isPrimitive(input.valueOf())) return input.valueOf(); throw new TypeError(); >function toNumber() < if (isPrimitive(input.valueOf())) return input.valueOf(); if (isPrimitive(input.toString())) return input.toString(); throw new TypeError(); >>

Методу [[ToPrimitive]] передаётся входное значение и предпочитаемый тип, к которому его надо преобразовать: Number или String . При этом аргумент preferredType необязателен.

И при конверсии в число, и при конверсии в строку используются два метода объекта, передаваемого [[ToPrimitive]] : это valueOf и toString . Оба метода объявлены в Object.prototype , и, таким образом, доступны для любого типа, основанного на Object , например — это Date , Array , и так далее.

В целом, работа алгоритма выглядит следующим образом:

  1. Если входное значение является примитивом — не делать ничего и вернуть его.
  2. Вызвать input.toString() , если результат является значением примитивного типа — вернуть его.
  3. Вызвать input.valueOf() , если результат является значением примитивного типа — вернуть его.
  4. Если ни input.toString() , ни input.valueOf() не дают примитивное значение — выдать ошибку TypeError .

Большинство встроенных типов не имеют метода valueOf , или имеют valueOf , который возвращает сам объект, для которого он вызван ( this ), поэтому такое значение игнорируется, так как примитивом оно не является. Именно поэтому преобразование в число и в строку может работать одинаково — и то и другое сводится к вызову toString() .

Различные операторы могут вызывать либо преобразование в число, либо преобразование в строку с помощью параметра preferredType . Но есть два исключения: оператор нестрогого равенства == и оператор + с двумя операндами вызывают конверсию по умолчанию ( preferredType не указывается или устанавливается в значение default ). В этом случае большинство встроенных типов рассматривают, как стандартный вариант поведения, конверсию в число, за исключением типа Date , который выполняет преобразование объекта в строку.

Вот пример поведения Date при преобразовании типов:

let d = new Date(); // получение строкового представления let str = d.toString(); // 'Wed Jan 17 2018 16:15:42' // получение числового представления, то есть - числа миллисекунд с начала эпохи Unix let num = d.valueOf(); // 1516198542525 // сравнение со строковым представлением // получаем true так как d конвертируется в ту же строку console.log(d == str); // true // сравнение с числовым представлением // получаем false, так как d не преобразуется в число с помощью valueOf() console.log(d == num); // false // Результат 'Wed Jan 17 2018 16:15:42Wed Jan 17 2018 16:15:42' // '+', так же, как и '==', вызывает режим преобразования по умолчанию console.log(d + d); // Результат 0, так как оператор '-' явно вызывает преобразование в число, а не преобразование по умолчанию console.log(d - d);

Стандартные методы toString() и valueOf() можно переопределить для того, чтобы вмешаться в логику преобразования объекта в примитивные значения.

var obj = < prop: 101, toString()< return 'Prop: ' + this.prop; >, valueOf() < return this.prop; >>; console.log(String(obj)); // 'Prop: 101' console.log(obj + '') // '101' console.log(+obj); // 101 console.log(obj > 100); // true

Обратите внимание на то, что obj + ‘’ возвращает ‘101’ в виде строки. Оператор + вызывает стандартный режим преобразования. Как уже было сказано, Object рассматривает приведение к числу как преобразование по умолчанию, поэтому использует сначала метод valueOf() а не toString() .

Метод Symbol.toPrimitive ES6

В ES5 допустимо менять логику преобразования объекта в примитивное значение путём переопределения методов toString и valueOf .

В ES6 можно пойти ещё дальше и полностью заменить внутренний механизм [[ToPrimitive]] , реализовав метод объекта [Symbol.toPrimtive] .

class Disk < constructor(capacity)< this.capacity = capacity; >[Symbol.toPrimitive](hint) < switch (hint) < case 'string': return 'Capacity: ' + this.capacity + ' bytes'; case 'number': // преобразование в KiB return this.capacity / 1024; default: // считаем преобразование в число стандартным return this.capacity / 1024; >> > // 1MiB диск let disk = new Disk(1024 * 1024); console.log(String(disk)) // Capacity: 1048576 bytes console.log(disk + '') // '1024' console.log(+disk); // 1024 console.log(disk > 1000); // true

Разбор примеров

Вооружённые теорией, вернёмся к выражениям, приведённым в начале материала. Вот каковы результаты вычисления этих выражений:

true + false // 1 12 / "6" // 2 "number" + 15 + 3 // 'number153' 15 + 3 + "number" // '18number' [1] > null // true "foo" + + "bar" // 'fooNaN' 'true' == true // false false == 'false' // false null == '' // false !!"false" == !!"true" // true ['x'] == 'x' // true [] + null + 1 // 'null1' 0 || "0" && <> // <> [1,2,3] == [1,2,3] // false <>+[]+<>+[1] // '0[object Object]1' !+[]+[]+![] // 'truefalse' new Date(0) - 0 // 0 new Date(0) + 0 // 'Thu Jan 01 1970 02:00:00(EET)0'

Разберём каждый из этих примеров.

▍true + false

Оператор + с двумя операндами вызывает преобразование к числу для true и false :

true + false ==> 1 + 0 ==> 1

▍12 / '6'

Арифметический оператор деления, / , вызывает преобразование к числу для строки '6' :

12 / '6' ==> 12 / 6 ==>> 2

▍«number» + 15 + 3

Оператор + имеет ассоциативность слева направо, поэтому выражение "number" + 15 выполняется первым. Так как один из операндов является строкой, оператор + вызывает преобразование к строке для числа 15 . На втором шаге вычисления выражения "number15" + 3 обрабатывается точно так же:

"number" + 15 + 3 ==> "number15" + 3 ==> "number153"

▍15 + 3 + «number»

Выражение 15 + 3 вычисляется первым. Тут совершенно не нужно преобразование типов, так как оба операнда являются числами. На втором шаге вычисляется значение выражения 18 + 'number' , и так как один из операндов является строкой — вызывается преобразование в строку.

15 + 3 + "number" ==> 18 + "number" ==> "18number"

▍[1] > null

Оператор сравнения > выполняет числовое сравнение [1] и null :

[1] > null ==> '1' > 0 ==> 1 > 0 ==> true

▍«foo» + + «bar»

Унарный оператор + имеет более высокий приоритет, чем обычный оператор + . В результате выражение +'bar' вычисляется первым. Унарный + вызывает для строки 'bar' преобразование в число. Так как строка не является допустимым числом, в результате получается NaN . На втором шаге вычисляется значение выражения 'foo' + NaN .

"foo" + + "bar" ==> "foo" + (+"bar") ==> "foo" + NaN ==> "fooNaN"

▍'true' == true и false == 'false'

Оператор == вызывает преобразование в число, строка 'true' преобразуется в NaN , логическое значение true преобразуется в 1 .

'true' == true ==> NaN == 1 ==> false false == 'false' ==> 0 == NaN ==> false

▍null == ''

Оператор == обычно вызывает преобразование в число, но это не так в случае со значением null . Значение null равно только null или undefined и ничему больше.

null == '' ==> false

▍!!«false» == !!«true»

Оператор !! конвертирует строки 'true' и 'false' в логическое true , так как они являются непустыми строками. Затем оператор == просто проверяет равенство двух логических значений true без преобразования типов.

!!"false" == !!"true" ==> true == true ==> true

▍['x'] == 'x'

Оператор == вызывает для массивов преобразование к числовому типу. Метод объекта Array.valueOf() возвращает сам массив, и это значение игнорируется, так как оно не является примитивом. Метод массива toString() преобразует массив ['x'] в строку 'x' .

['x'] == 'x' ==> 'x' == 'x' ==> true

▍[] + null + 1

Оператор + вызывает преобразование в число для пустого массива [] . Метод объекта Array valueOf() игнорируется, так как он возвращает сам массив, который примитивом не является. Метод массива toString() возвращает пустую строку.

На втором шаге вычисляется значение выражения '' + null + 1 .

[] + null + 1 ==> '' + null + 1 ==> 'null' + 1 ==> 'null1'

▍0 || «0» && <>

Логические операторы || и && в процессе работы приводят значение операндов к логическому типу, но возвращают исходные операнды (которые имеют тип, отличный от логического). Значение 0 ложно, а значение '0' истинно, так как является непустой строкой. Пустой объект <> так же преобразуется к истинному значению.

0 || "0" && <> ==> (0 || "0") && <> ==> (false || true) && true // внутреннее преобразование ==> "0" && <> ==> true && true // внутреннее преобразование ==> <>

▍[1,2,3] == [1,2,3]

Преобразование типов не требуется, так как оба операнда имеют один и тот же тип. Так как оператор == выполняет проверку на равенство ссылок на объекты (а не на то, содержат ли объекты одинаковые значения) и два массива являются двумя разными объектами, в результате будет выдано false .

[1,2,3] == [1,2,3] ==> false

▍<>+[]+<>+[1]

Все операнды не являются примитивными значениями, поэтому оператор + начинается с самого левого и вызывает его преобразование к числу. Метод valueOf для типов Object и Array возвращают сами эти объекты, поэтому это значение игнорируется. Метод toString() используется как запасной вариант. Хитрость тут в том, что первая пара фигурных скобок <> не рассматривается как объектный литерал, она воспринимается как блок кода, который игнорируется. Вычисление начинается со следующего выражения, +[] , которое преобразуется в пустую строку через метод toString() , а затем в 0.

<>+[]+<>+[1] ==> +[]+<>+[1] ==> 0 + <> + [1] ==> 0 + '[object Object]' + [1] ==> '0[object Object]' + [1] ==> '0[object Object]' + '1' ==> '0[object Object]1'

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

!+[]+[]+![] ==> (!+[]) + [] + (![]) ==> !0 + [] + false ==> true + [] + false ==> true + '' + false ==> 'truefalse'

▍new Date(0) — 0

Оператор - вызывает преобразование в число для объекта типа Date . Метод Date.valueOf() возвращает число миллисекунд с начала эпохи Unix.

new Date(0) - 0 ==> 0 - 0 ==> 0

▍new Date(0) + 0

Оператор + вызывает преобразование по умолчанию. Объекты типа Data считают таким преобразованием конверсию в строку, в результате используется метод toString() , а не valueOf() .

new Date(0) + 0 ==> 'Thu Jan 01 1970 02:00:00 GMT+0200 (EET)' + 0 ==> 'Thu Jan 01 1970 02:00:00 GMT+0200 (EET)0'

Итоги

Преобразование типов — это один из базовых механизмом JavaScript, знание которого является основой продуктивной работы. Надеемся, сегодняшний материал помог тем, кто не очень хорошо разбирался в неявном преобразовании типов, расставить всё по своим местам, а тем, кто уверенно, с первого раза, никуда не подсматривая, смог решить «вступительную задачу», позволил вспомнить какой-нибудь интересный случай из их практики.

Уважаемые читатели! А в вашей практике случалось так, чтобы путаница с неявным преобразованием типов в JavaScript приводила к таинственным ошибкам?

  • Блог компании RUVDS.com
  • Веб-разработка
  • JavaScript

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *