Как стать автором
Обновить
31
Карма
0
Рейтинг
Александр Кривощёков @SuperPaintman

Lead Software Engineer / Backend / Go / C++

  • Подписчики 54
  • Подписки

9 полезных приёмов для тех, кто программирует на JavaScript

Заметьте, я и не говорил про спецификацию, я сказал про JS движки (V8 / Spider Monkey / etc.) и их оптимизацию такого поведения, что я не уверен, что подобное использование length не деоптимизирует байт код.


Касаемо спеки, да, данное поведение в ней явно прописано.

9 полезных приёмов для тех, кто программирует на JavaScript

Исходя из поста, знание основ любого языка — признак профессионализма.


1. Очистка или усечение массива

А за такое можно сразу гнать из профессии. Мало того, что это, мягко скажем, необычное применение для length, это, предполагаю, может подгадить в плане оптимизации кода JS движком. Не говоря уж о том, что JS не требует ручного управления памятью.


4. Использование диапазонов значений в операторе switch

А почему нельзя было через if/else?

Почему не стоит использовать LocalStorage

Во-первых, как уже было сказано выше, Cookie — ~4kB т.е. 4k char. В среднем, я не использовал JWT токены длинее 2k символов, но это не показатель, и ваш JWT может быть и в 8kB.


Во-вторых, cookie постоянно гоняются по сети, даже если вы этого не хотите (fetch и XMLHttpRequest не в счет, там по умолчанию false).

Может ли в JavaScript конструкция (a==1 && a==2 && a==3) оказаться равной true?

Да, т.к. document.getElementById('layer1').style.opacity — это строка, а не число.


И формально, это равносильно этому:


let a = '0.2';

a += 0.01; // Тут Number преобразуется в строку

console.log(a); // => 0.20.01

Но тут уже важно понимание дела, т.е. TS не знает, хотите ли вы добавить символы в строку, или сложить числа.


И Flow сделает то-же самое: https://flow.org/try/#0DYUwLgBAhhC8EHICMCDcAodMDU8BMG6AxgPYB2AziaAHTAkDmAFFAJSoQD0ncAfBEjxA

Может ли в JavaScript конструкция (a==1 && a==2 && a==3) оказаться равной true?

Тут трудно не согласиться (я об это тоже сказал чуть выше). Но мы все-же говорим в контексте JS.


Собственно, надеюсь, я правильно понял вашу позицию. TS действительно крутой :).

Может ли в JavaScript конструкция (a==1 && a==2 && a==3) оказаться равной true?

Вы абсолютно правы, что язык должен в первую очередь быть инструментом, а не целью. Но в большинстве языков: Python — input(), C — getchar(), Ruby — gets, инпут — это строка.


Так и в JS, input Dom node — содержит исключительно строки.

Может ли в JavaScript конструкция (a==1 && a==2 && a==3) оказаться равной true?

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

Может ли в JavaScript конструкция (a==1 && a==2 && a==3) оказаться равной true?

(простите, опечатался, не "a", а конечно же "x" станет числом тоже).


И в целом то, это проблема не JS, а вообще динамических языков, и языков с хоть чуть-чуть возможностью переопределять операторы или (и) неявно приводить типы.


# Python
>>> "5" * 10 + "8"
'55555555558'

Т.е. тут вопрос скорее к невнимательности. И тут TS или Flow, бы решили эту проблему (ну или попытались :) ).

Может ли в JavaScript конструкция (a==1 && a==2 && a==3) оказаться равной true?

И нет, "a" — не останется строкой, т.к. "-" тоже кастует в Number

Может ли в JavaScript конструкция (a==1 && a==2 && a==3) оказаться равной true?

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


const a = 0.1;
const x = +document.querySelector('input[name="x"]').value; // Вот теперь это число
const y = +document.querySelector('input[name="y"]').value; // И это тоже

console.log(x - a * y)

Хотя parseInt(n, 10) все-же более наглядно и конвертирует исключительно в десятичное число (т.к. +'0xFF' === 255).


По-хорошему, нужно x и y сконвертировать в число в момент присвоения

С чего бы это? Инпут хранит исключительно значение как строку, а если вы про input[type="number"] — то это не имеет никакого отношения к JS, это лишь валидация пользовательского инпута, как и type="email", а в JS это приходит как обычная DOMString.

Может ли в JavaScript конструкция (a==1 && a==2 && a==3) оказаться равной true?

Если интерпретатор написан по-стандарту (и здравому смыслу), && будут идти слева-направо. V8 / SpiderMonkey / Chakra работают именно так

Может ли в JavaScript конструкция (a==1 && a==2 && a==3) оказаться равной true?

Не совсем понимаю за что вас минусуют. Если вы не против, я добавлю комментарии к вашему коду, что-бы читателям стало понятно.


Для начала, это абсолютно валидный код с точки зрения C.


#define директива — это по-сути замена во время компиляции найденого токена (или вызова) на его значени. В случае выше, любая найденная a будет заменена на (__COUNTER__+1)


__COUNTER__ — это "магическое" макро значение, как и __FILE__, __LINE__, или __FUNCTION_. И в C / C++ эти значения опять же заменяются на этапе компиляции (см. выше). Сам же __COUNTER__ "магичен" из-за того, что при каждом новом вызове, он будет инкриментировать свое значение (от 0).
В итоге выражение (__COUNTER__+1) станет (0+1), затем (1+1), затем (2+1).


И весь код будет выглядеть так:


// Т.к. `include` тоже макрос, тут будет содержимое этого файла.

int main(void) {
    if ((0+1) == 1 && (1+1) == 2 && (2+1) == 3) printf("123123123");
    return 0;
}

А дальше все еще круче, если кому интересно, компилятор просто схлопнет (оптимизирует) константные выражения, и на выходе останется:


// Т.к. `include` тоже макрос, тут будет содержимое этого файла.

int main(void) {
    printf("123123123");
    return 0;
}

Так-что не спешите кидаться на zawodskoj

Вашим пользователям не нужны пароли

А что, если злобный админ поставит прокси перед /api/signin и будет писать не захешированные пароли (а напомню, они именно так по сети гуляют) в файлик?


И опять же, см. пункт с ресетом пароля, если он есть, то вы и так сможете получить письмо.

Вашим пользователям не нужны пароли

Могу ошибаться, но у Github синхронизация только между табами одного устройства, и скорее всего через localstorage / cookie в браузере.


А вот с подходом, описанном выше, так не получится. Нужен сервер в любом случае.

Вашим пользователям не нужны пароли

Но нужно еще продумать о безопасность этого подхода, т.к. хранить только email в клиентской сессии, вообще не безопасно, нужно тогда возвращать какой-нибудь секрет от запроса, сгенерированный бэком, а также хранить его в sign_in_requests таблице.


С хранением на бэке, примерна такая-же история, нужно будет записывать guid сессии (cookie-based сессии) в таблицу sign_in_requests, и опять же сверять при рефреше сочетание email + secret.

Вашим пользователям не нужны пароли

Если я вас правильно понял, вы хотите, чтобы страница (с которой отправлен запрос) сама перезагрузилась, когда вы перейдете по ссылке из письма. Идея хорошая, но тут может появиться излишние затраты либо на Long polling, либо на полноценный Web socket (запросы по таймаута — зверство, поэтому я их не рассматриваю). Но этот вариант может решить проблему с телевизорами / IoT'ами.


Можно сделать менее красивый, но и менее затратный вариант: запоминать email на который выслали письма, а после ручного рефреша страницы (или перехода на другую страницу) проверять, перешел ли пользователь по ссылке из письма и окончательно авторизовать его. Т.е. получается такая двух этапная авторизация, на первом шаге мы просто записали email в переменную сессии (localstorage / cookie / backend session), а после подтверждения активировали эту сессию.

Вашим пользователям не нужны пароли

У нас есть HTTPS, а с Lets Encrypt вообще нет ни одной причины не использовать его.


К слову, а подтверждая email переходом из того же письма, вы более устойчивы к MITM?

Вашим пользователям не нужны пароли

Использование внешнего сервиса — это само по себе риск, даже в не самых критичных частях системы. Вы просто никак не можете работать с этим риском и влиять на него, особенно если это крупные сервисы типа mail.ru/gmail.com/

А что вам в предложенной схеме мешает использовать свой почтовый сервер, если вы не доверяете гуглу?


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

К сожалению, я склонен больше верить в то, что у сайта с "котиками" будет все плохо, нежели у Yandex / Google / Mail.


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

А почему в предложено выше варианте они не могут сосуществовать? Вы можете позволить пользователю самостоятельно сделать выбор чем он хочет пользоваться: Oauth / Email + Pass / Email.


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

Вашим пользователям не нужны пароли

Использовать телефон (СМС) гораздо доже и менее безопасно, чем почту.


А если предположить, что номер телефона может утечь, то начнется спам. А вот спам на телефон в разы более мерзкий, чем на email. Если у email сервисов уже отлажены методы борьбы со спамом, то вот у телефонов все плачевно, будете получать звонки от "пирамид" с разных номеров.

Вашим пользователям не нужны пароли

Автор просто предлагает переложить заботу о хранении пароля на чужие плечи.

Так она и не слезала с их плеч. Т.е. если у вас есть сброс пароля — у вас и не было никогда пароля. Multi kill


Хорошие варианты — это жесты на фотках. Составление из некоторых объектов пространственной фигуры и так далее.

Так и вижу, как я бегаю по комнате ищя кубики, чтобы авторизоваться на хабре :).

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность