Pull to refresh

Comments 36

Хорошая статья, может сэкономить много нервных клеток новичкам, которые начинают писать на js после других языков.
По поводу Python, можете пояснить подробнее, что подразумевается под динамическим созданием функций и свойствами функций, и чего нету (?) в питоне? Ну и для замыканий в 3ем питоне есть nonlocal. Какие ещё возможности ограничены?
В результате JavaScript обрёл довольно плохую репутацию, которой он, в общем-то, не заслуживает.

Имхо, взамен неудобному DOM API существует вполне удобный jQuery, так что он к репутации JS имеет мало отношения. А вот что действительно подрывает доверие — это пируэты неявного приведения типов, неортогональность стандартной библиотеки и прочий WAT. Причина этого не в привычке к Java и C++, а исключительно в том, что у автора первой версии JS не было времени на проработку деталей, которые впоследствии стало невозможно поменять без разрушения обратной совместимости.
Книга «JavaScript: The Good Parts» (Douglas Crockford) как раз об этом.
Неявное приведение типов — источник множества приёмов сокращения кода. Просто, людям бывает лень нормально изучить язык…
Проблема в том, что у JS кардинально поменялась область применения, а инструментарий остался тем же самым. Возможность написать две магические строчки и получить результат была хороша только на том этапе, когда JS не использовался для вещей сложнее падающих снежинок. Для разработки сколько-нибудь сложного проекта куда важнее читаемость и поддерживаемость, потому что иначе рефакторинг автоматически превращается в ночной кошмар. А для уменьшения исходников есть минификаторы…
Верно. Но суть в том, что строчки-то не магические. А общепринятые в JavaScript-разработке.
//Анахронизм
if(typeof value == 'undefined'){
value = devaultValue;
}
//Стандарт
value = value || defaultValue;

Читаемость достигается за счёт знания языка всеми разработчиками.
Вы рано списали оператор typeof в утиль, поскольку приведенные вами варианты не однозначны. Если значение false или 0 допустимо, то оператор || может стать причиной неприятного труднообнаруживаемого бага:

// отключить страницу невозможно
page.isEnabled = viewModel.isEnabled || true;
Верно.
//По умолчанию - true
page.isEnabled = viewModel.isEnabled !== false;
Статья хорошая, но:

недовольны следующими моментами:

  • DOM, который многие ошибочно считают эквивалентом самого языка JavaScript, обладает очень неудачным API.
  • Когда переходишь на JavaScript с языков С и Java, то попадаешь в ловушку синтаксиса, который устроен не так, как в императивных языках. Это очень часто приводит к багам и сильно раздражает.


В результате JavaScript обрёл довольно плохую репутацию, которой он, в общем-то, не заслуживает.


Свою репутацию плохого языка ЖС полностью заслуживает и не из за этих двух абстрактных причин а из-за огромного количества ошибок, дыр и спорных моментов в дизайне и логике языка. Например (таких примеров очень много, можно продолжать очень долго):

> ',,,' == new Array(4) //true
> {} + [] //0
> [] + [] //"[object Object]"
И еще вот это, мое любимое:
  {} + {}   // NaN
( {} + {} ) // "[object Object][object Object]"
Полностью отказаться от преобразования типов?
Увы, так не получится. Зато было бы неплохо ввести какой-нибудь super strict mode, где были бы запрещены большинство бессмысленных преобразований и остались только следующие:

  • Преобразование любого объекта к строке
  • Преобразование любого объекта к true / false
  • Преобразование bool и string в number

Все остальные, особенно многозвенные (типа array -> string -> number) — это только лишний способ выстрелить себе в ногу.
С такой формулировкой согласен, за исключением: должна остаться возможность определить valueOf и toString.
По дефолту у объекта — да, лучше бы они эксцепшен кидали.
Зато было бы неплохо ввести какой-нибудь super strict mode

Уже: "Experiments with Strengthening JavaScript".

Учитывая обилие линтеров и чекеров типа flowtype можно писать
нормально, а можно маразматичную лапшу.

Как можно выстрелить себе в ногу неявными преобразованиями мне себе сложно представить.

UFO just landed and posted this here
Типизация говорите? Динамическая? Только я немного не об этом а скорей вот о чем:

var a = new Array(4) //undefined
a //[undefined × 4]
a[0] //undefined
String(a[0]) //"undefined"
String(a) //",,,"
То что вы показали мало отношения к массивам имеет. String(undefined) === «undefined»
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Это конечно всеми любимый довод, но если вы такой код пишите, то наверное с вами что то не так. =)
На многих конференциях на эту тему говорят что то вроде «не пишите подобный код» с чем трудно не согласиться.
Сами идеи сравнения строки с массивом или складывание объекта с массивом весьма сомнительны.
Если разработчики перестанут писать такой код это к сожалению не исправит огромное количество ошибок, дыр и спорных моментов в дизайне и логике языка.
Ошибок и дыр? Например?
Чем Вам не угодило неявное приведение типов? Так трудно запомнить, что к чему приводится?
Вы удивитесь, но для кого-то это действительно трудно. Мне, например, логика этих правил оказалась неподвластна. К частью, в Typescript большинство таких неявных приведений типа '2' * '3' запрещены компилятором.
Кстати, респект переводчику за бережное отношение к форматированию статьи — в особенности за теги <code> и равномерные отступы у абзацев. Еще было бы очень здорово к переведенным терминам давать англоязычный вариант, например так: поднятие переменных.
UFO just landed and posted this here
UFO just landed and posted this here
Отличная статья. Спасибо!
Единственное что режет взгляд это «декларирование» переменных и функций — это актуально в английском тексте (declare), по русски их все-таки «объявляют» =)
Очень любопытно, но let в фф поддерживается, а в сводной таблице упорно пишется, что это не так.
Можете запустить в консоли:
let foo = 123; (foo === 123);

let bar = 123; { let bar = 456; } bar === 123;

let baz = 1; for(let baz = 0; false; false) {} baz === 1;

При чём отмечу интересный факт: что пока эти тесты проходятся в табличке зияет 8/10 успешно, а в графах ФФ38 и ФФ39 5/10. Но после окончания они сразу окрашиваются в красный, и выставляется 0/10…
Во-первых они чёрти где
Во-вторых в колонке current нету сносок (т.е. не мешало бы и проверить)

И, вообще, очень странно состояние флага ставить выше реальной поддержки (обычно окрашивают как-то иначе, когда есть условия неработоспособности). Кода с <script type='application/javascript;version=1.7'> я не встречал чего-то. В итоге автор (видимо так же не прочитав сноски объяявляет, что let поддерживается только в хроме, что не правда, которая сильно путает. Потом я слышу от сторонних разработчиков, что вот, let нельзя использовать ибо только хром умеет с ним работать, читал там-то. =/
Sign up to leave a comment.