Рубрики
Без рубрики

Незнакомецные вещи, JavaScript Edition

Сегодня мы собираемся сделать специальный пост, посвященный этим странным моментам JavaScript, где вещи будут … помечены JavaScript, программированием, узлом, инженером программного обеспечения.

Сегодня мы собираемся сделать специальный пост, посвященный тем странным моментам JavaScript, где веща себя немного странно.

«Никто нормально никогда не достигл ничего значимого в этом мире». — Джонатан, незнакомец

Мы рассмотрим некоторые фрагменты кода с удивительными результатами, и мы сделаем объяснение того, что происходит, так что мы можем лучше понять наш любимый язык программирования. Хотя это чудак, мы любим это!

Сценарий № 1: [‘1’, ‘7’, ’11’]. Карта (Парсент)

Давайте посмотрим на код для нашего первого сценария

['1', '7', '11'].map(parseInt);

За то, что вы ожидаете, что вывод будет:

[1, 7, 11]

Тем не менее, все здесь получают немного, а фактический результат:

[1,NaN,3]

Сначала это может выглядеть очень странно, но на самом деле он имеет элегантное объяснение. Чтобы понять, что происходит, нам нужно понять 2 вовлеченных функции, карта и Парсент Отказ

карта()

карта () Звонит предоставленные Обратный вызов Функция один раз для каждого элемента В массиве, по порядку и создают новый массив из результатов. Обратный вызов вызывается только для индексов массива, которые назначили значения (включая undefined ).

Теперь Обратный вызов Приведенные выше функция приведены некоторые конкретные параметры, давайте возьмем пример с его выходом:

[1, 2, 3].map(console.log)
1 1 0 > (3) [1, 2, 3]
1 2 1 > (3) [1, 2, 3]
1 3 2 > (3) [1, 2, 3]

Как видно, функция карты не только передала значение элемента, но и индекс и копию полного массива на каждой итерации. Это важно и частично влияет на наш предыдущий результат.

Parсент ()

Parсент () Функция анализирует строковый аргумент и возвращает целое число указанного радикса (база в математических числовых системах).

Так что теперь по определению, Parсент (строка [, Radix]) ожидает двух параметров, строка, которую мы хотим разбираться, и радикс.

Решение тайны

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

['1', '7', '11'].map(parseInt);

Как мы знаем Обратный вызов для карта Функция получит 3 аргумента, поэтому давайте сделаем это:

['1', '7', '11'].map((currentValue, index, array) => parseInt(currentValue, index, array));

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

parseInt('1', 0)
1
parseInt('7', 1)
NaN
parseInt('11', 2)
3

Так что теперь объясняет значения, которые мы увидели изначально, Парсент Результат функции изменяется по редикс Параметр, который определяет базу для преобразования.

Есть ли способ получить первоначально ожидаемый результат?

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

['1', '7', '11'].map((currentValue) => parseInt(currentValue));
> (3) [1, 7, 11]

Сценарий № 2: («B» + ‘A’ + + ‘A’ + ‘A’). TolowerCase ()

Вы можете думать, что выражение выше является ложным, в конце концов, в строке нет буквы «n», мы строим на левой стороне выражения, или не так ли? Давайте узнаем:

('b'+'a'+ + 'a' + 'a').toLowerCase() === 'banana'
true

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

('b'+'a'+ + 'a' + 'a').toLowerCase()
"banana"

Интересно, что мы формируем слово «банана», поэтому проблема кажется здесь, давайте удалим строчную конверсию и посмотрим, что произойдет:

('b'+'a'+ + 'a' + 'a')
"baNaNa"

Бинго! Мы нашли несколько «n» сейчас, и выглядит так, как мы нашли Нан Внутри строки, возможно, это приходит из + + Выражение, давайте притворяться, что и посмотрим, что мы бы получили:

b + a + NaN + a + a

Не совсем хорошо, у нас есть дополнительные А Так что давайте попробуем что-то еще:

+ + 'a'
NaN

Ааа там мы идем … + + Операция сама по себе не оценивается, но когда мы добавляем символ «A» в конце, все это входит в Нан Теперь вписывается в наш код. Нан Выражение затем объединяется как строка с остальной частью текста, и мы наконец получаем банан . Довольно странно!

Сценарий № 3: не могу даже назвать это

(![] + [])[+[]] +
  (![] + [])[+!+[]] +
  ([![]] + [][[]])[+!+[] + [+[]]] +
  (![] + [])[!+[] + !+[]] === 'fail'

Что в мире? Как пучок скобок образует слово не удастся? И поверьте мне, js не проводит, мы на самом деле получаем строку потерпеть неудачу в качестве вывода.

Давайте постараемся объяснить это, в этой группе есть несколько вещей, которые образуют шаблон:

(![] + [])

Этот шаблон оценивает на строку ложь , что странно, но его свойство языка, оказывается, что false + [] Эта трансформация имеет отношение к тому, как JS внутренние сопоставления внутренних звонков, мы не будем решать детали относительно того, почему это точно происходит.

Как только вы образуете строку ложь Остальные легко, просто ищите позиции букв, которые вам нужны, кроме одного случая, письмо Я что не является частью слова ложь Отказ

Для этого исходное выражение немного изменилось, давайте посмотрим на него ([! []] + [] [] [[]) который оценивает строку falseundeded . Так что в основном мы заставляем неопределенную ценность и объединить его на ложь Строка мы знаем, как получить, а остальные это история.

Любить это так далеко? Давайте сделаем еще немного.

Сценарий № 4: Быть правдивым или быть правдой, это вопрос.

Быть правдой или быть правдой, это вопрос. Быть ложным или быть ложным, это вопрос.

Что такое истина и фальсификация? И почему они отличаются от правдой или ложного?

Каждое значение в JavaScript в качестве собственного логического значения (правдоподобное/Falsy) эти значения используются в операциях, где ожидается булева, но не дано. Скорее всего, вы хотя бы один раз делал что-то подобное:

const array = [];
if (array) {
  console.log('Truthy!');
}

В коде выше, Массив не булевой, даже если ценность «правда», и выражение приведет к выполнению console.log ниже.

Откуда я знаю, что такое истина и что является фальсию?

Все, что не является ложностью, правда. Страшное объяснение? Достаточно честно, давайте рассмотрим его дальше.

Falsy – это ценности с унаследованным логией ложь , ценности, как:

  • 0
  • -0
  • ” или ” “
  • нулевой
  • неопределенный
  • Нан

Все остальное было бы правдой.

Сценарий № 5: Равенство массива

Некоторые вещи в JS просто странные, это так, как язык дизайн, и мы принимаем это так, как оно есть. Давайте посмотрим некоторые странные равенства массива:

[] == ''   // -> true
[] == 0    // -> true
[''] == '' // -> true
[0] == 0   // -> true
[0] == ''  // -> false
[''] == 0  // -> true

[null] == ''      // true
[null] == 0       // true
[undefined] == '' // true
[undefined] == 0  // true

[[]] == 0  // true
[[]] == '' // true

[[[[[[]]]]]] == '' // true
[[[[[[]]]]]] == 0  // true

[[[[[[ null ]]]]]] == 0  // true
[[[[[[ null ]]]]]] == '' // true

[[[[[[ undefined ]]]]]] == 0  // true
[[[[[[ undefined ]]]]]] == '' // true

Если вы заинтересованы в том, почему? Вы можете прочитать его в разделе 7.2.13 Абстрактное сравнение равенства спецификации. Хотя я должен предупредить вас, это не для нормальных людей: p.

Сценарий № 6: Математика математика, если ….

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

3  - 1  // -> 2
 3  + 1  // -> 4
'3' - 1  // -> 2
'3' + 1  // -> '31'

'' + '' // -> ''
[] + [] // -> ''
{} + [] // -> 0
[] + {} // -> '[object Object]'
{} + {} // -> '[object Object][object Object]'

'222' - -'111' // -> 333

[4] * [4]       // -> 16
[] * []         // -> 0
[4, 4] * [4, 4] // NaN

Первоначально все началось хорошо, пока мы не доберемся до:

'3' - 1  // -> 2
'3' + 1  // -> '31'

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

Number  + Number  -> addition
Boolean + Number  -> addition
Boolean + Boolean -> addition
Number  + String  -> concatenation
String  + Boolean -> concatenation
String  + String  -> concatenation

Как насчет других примеров? A Отправляющий и TOSTRING Методы неявно вызываются для [] и {} перед добавлением. Узнайте больше о процессе оценки в спецификации:

Примечательно, {} + [] Вот исключение. Причина, по которой это отличается от [] + {} Это, без скобки, он интерпретируется как код код, а затем unary +, преобразование [] в число. Это видит следующее:

{
  // a code block here
}
+[]; // -> 0

Чтобы получить тот же выход, что и [] + {} Мы можем обернуть его в скобках.

({} + []); // -> [object Object]

Заключение

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

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

Спасибо за прочтение!

Оригинал: “https://dev.to/livecodestream/stranger-things-javascript-edition-3lfi”