JavaScript как воплощение зла  



JavaScript как воплощение зла +8

JavaScript-разработчики часто жалуются на то, что их язык программирования несправедливо ругают за то, что он имеет слишком много чрезмерно усложнённых, запутанных возможностей. Многие борются с таким отношением к JS, рассказывая о том, почему критиковать этот язык за то, чем он является, неправильно. Автор материала, перевод которого мы сегодня публикуем, решил не защищать JS, обратившись, вместо этого, к тёмной стороне языка. Однако тут он не хочет говорить, например, о тех ловушках, которые JavaScript расставляет для неопытных программистов. Его интересует вопрос о том, что получится, если попытаться подтвердить плохую репутацию языка кодом, который мог бы написать тот, кто совершенно не заботится об окружающих.



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

Геттеры-модификаторы


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

let greeter = {
  name: 'Bob',
  get hello() { return `Hello ${this.name}`}
}
console.log(greeter.hello) // Hello Bob
greeter.name = 'World';
console.log(greeter.hello) // Hello World

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

let obj = {
   foo: 1,
   bar: 2,
   baz: 3,
   get evil() {
      let keys = Object.keys(this);
      if(keys) {
         delete this[keys[0]]
      }
      return 'Nothing to see here';
   }
}

Здесь, при каждом обращении к obj.evil, будет удаляться одно из других свойств объекта. При этом код, работающий с obj.evil, не будет знать о том, что прямо у него под носом происходит нечто весьма странное. Однако, это — только начало разговора о вредных побочных эффектах, которых можно добиваться с помощью механизмов JavaScript.

Неожиданные прокси


Геттеры — это здорово, но они существуют уже многие годы, о них знает множество разработчиков. Теперь же, благодаря прокси, в нашем распоряжении оказывается куда более мощный инструмент для развлечений с объектами. Прокси — это возможность ES6, которая позволяет создавать обёртки вокруг объектов. С их помощью можно управлять тем, что происходит, когда пользователь пытается читать или записывать свойства проксируемых объектов. Это позволяет, например, создать объект, который, в одной трети попыток доступа к некоему ключу такого объекта, будет возвращать значение по случайно выбранному ключу.

let obj = {a: 1, b: 2, c: 3};

let handler = {
    get: function(obj, prop) {
      if (Math.random() > 0.33) {
        return obj[prop];
      } else {
        let keys = Object.keys(obj);
        let key = keys[Math.floor(Math.random()*keys.length)]
        return obj[key];
      }
    }
};

let evilObj = new Proxy(obj, handler);

// вот что может получиться при работе с подобным объектом
console.log(evilObj.a); // 1
console.log(evilObj.b); // 1
console.log(evilObj.c); // 3
console.log(evilObj.a); // 2
console.log(evilObj.b); // 2
console.log(evilObj.c); // 3

Нашу подлость, к сожалению, частично раскрывают инструменты разработчика, идентифицирующие evilObj как объект типа Proxy. Однако, вышеописанная конструкция, до того, как будет раскрыта её низменная сущность, способна доставить тем, кто будет с ней работать, немало приятных минут.

Заразные функции


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

let get = (obj, property, default) => {
   if(!obj) {
      return default;
   }
   return obj[property];
}

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

let get = (obj, property, defaultValue) => {
   if(!obj || !property in obj) {
      return defaultValue;
   }
   let value = obj[property];
   delete obj[property];
   Object.defineProperty(obj, property, {
      value,
      enumerable: false
   })
   return obj[property];
}

let x = {a: 1, b:2 };

console.log(Object.keys(x)); // ['a', 'b']
console.log(get(x, 'a'));
console.log(Object.keys(x)); // ['b']

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

Прототипный беспорядок


Выше мы обсуждали разные возможности JS, в том числе — и довольно свежие. Однако иногда нет ничего лучше, чем старые, проверенные временем технологии. Одной из особенностей JS, из-за которой на него обрушивается больше всего критики, является возможность модификации встроенных прототипов. Эта возможность использовалась в ранние годы JS для расширения встроенных объектов, например — массивов. Вот как расширить стандартные возможности массивов, скажем, добавив к прототипу объекта Array метод contains:

Array.prototype.contains = function(item) {
  return this.indexOf(item) !== -1;
}

Как оказывается, если сделать что-то подобное в реально используемой библиотеке, это может нарушить работу с базовыми механизмами языка во всём приложении, использующем эту библиотеку. Поэтому включение дополнительных полезных методов в прототипы стандартных объектов можно считать весьма удачным ходом для терпеливых разработчиков, которые стремятся делать другим гадости. Однако если речь идёт о нетерпеливых социопатах, им можно предложить кое-что быстродействующее, но не менее интересное. У модификации прототипов есть одно весьма полезное свойство, которое заключается в том, что модификация воздействует на весь код, который выполняется в некоем окружении, даже на тот, который загружается из модулей или находится в замыканиях. В результате, если оформить следующий код в виде стороннего скрипта (скажем, это может быть скрипт рекламной сети или аналитической службы), то весь сайт, использующий этот скрипт, окажется подверженным небольшим ошибкам.

Array.prototype.map = function(fn) {
   let arr = this;
   let arr2 = arr.reduce((acc, val, idx) => {
      if (Math.random() > 0.95) {
         idx = idx + 1
      }
      let index = acc.length - 1 === idx ? (idx - 1 ) : idx
      acc[index] = fn(val, index, arr);
      return acc;
   },[]);
   return arr2;
}

Тут мы переопределили стандартный метод Array.prototype.map так, что он, в целом, работает нормально, но в 5% случаев меняет местами два элемента массива. Вот что можно получить после нескольких вызовов подобного метода:

let arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
let square = x => x * x;
console.log(arr.map(square));
// [1,4,9,16,25,36,49,64,100,81,121,144,169,196,225
console.log(arr.map(square));
// [1,4,9,16,25,36,49,64,81,100,121,144,169,196,225]
console.log(arr.map(square));
// [1,4,9,16,25,36,49,64,81,100,121,144,169,196,225]

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

Непростые имена


Именование сущностей, как известно, является одной из двух сложнейших задач компьютерной науки. Поэтому плохие имена придумывают не только те, кто сознательно стремится навредить другим. Конечно, в это может быть трудно поверить бывалым линуксоидам. В их распоряжении были годы на то, чтобы связать страшнейшего IT-нарушителя в сфере именования (Microsoft) с глубочайшими формами зла. Но неудачные имена не приносят прямого вреда программам. Не будем говорить о мелочёвке вроде имён, вводящих в заблуждение и о потерявших актуальность комментариях. Например, о таких:

// Инициализация даты
let arrayOfNumbers = { userid: 1, name: 'Darth Vader'};

Для того чтобы в это вникнуть и понять, что тут что-то не так и с комментарием, и с именем переменной, тому, кто читает код, в котором встречается подобное, придётся малость притормозить и подумать. Но это — ерунда. Давайте лучше поговорим о по-настоящему интересных штуках. Вы знали, что большинство Unicode-символов можно использовать для именования переменных в JavaScript? Если вы, в вопросе назначения имён переменных, настроены на позитив, то вам понравится идея использования имён в виде значков (Хабр вырезал emoji, хотя в оригинале тут после let была emoji какахи):

let  = { postid: 123, postName: 'Evil JavaScript'}

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

let obj = {};
console.log(obj); // Error!

Буква b в имени obj может выглядеть почти нормально, но это — не строчная латинская буква b. Это — так называемая полноширинная строчная латинская буква b. Символы это разные, поэтому любой, кто попытается ввести имя подобной переменной вручную, скорее всего, окажется сильно сбитым с толку.

Итоги


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

Уважаемые читатели! Сталкивались ли вы на практике с чем-то похожим на то, о чём шла речь в этой статье?

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (61):

  1. nafgne
    /#18886081 / +9

    — пишем функцию, творящую трэш
    — вызываем её
    — получаем трэш
    у д и в и т е л ь н о

    • alhimik45
      /#18886093 / +5

      +1. Да и причём тут вообще Javascript? Подобный трэш можно написать на любом языке(вспомним знаменитое #define true false).

      • valeriyk
        /#18886307

        Это еще что. Тут недавно попалось #define volatile

      • mapron
        /#18886339 / +2

        Ну или согласно другому примеру статьи
        #define true (rand() % 20 > 0)

    • Splean
      /#18886115 / -6

      Трешовый код может быть в сторонних модулях, которые в большом количестве используются в проектах на JavaScript

      • akurganow
        /#18886127 / +5

        Как и в других языках

        • Splean
          /#18886141 / -4

          И как и в других языках нужно знать про источники возможных проблем. Зачем вы приплетаете другие языки когда статья про JavaScript — не понятно

          • abyrkov
            /#18886365 / +4

            Суть в том, что статья применима не только к JS.

      • PYXRU
        /#18886129 / +1

        И как вы от этого обезопаситесь? Проблема надумана полностью. Статью можно заменить одним предложением: "Чтобы говна не было, не испражняйтесь"

        • Splean
          /#18886147 / -3

          Я ответил в комментарии выше

          • PYXRU
            /#18886179 / +1

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

            • Splean
              /#18886229 / -1

              Всегда нравилось как люди рассуждают с позиции своего Я :) Зачем учить людей программировать и писать о возможностях языка? Это же и так очевидно. Зачем маленький ребенок засунул гвоздь в розетку, а потом плачет, очевидно же что его ударит током :)
              А если отвлечься от лирики, автор статьи с самого начала сообщил что он намеренно рассматривает «темные стороны языка» которые воспроизводятся и на других языках. Где вы тут увидели героизм и связь с реальными кейсами непонятно :)

              • PYXRU
                /#18886277 / +1

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

              • StallinHrusch
                /#18887139

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

                — пишем функцию, творящую трэш
                — вызываем её
                — получаем трэш
                у д и в и т е л ь н о

        • Mabusius
          /#18886601 / +2

          Вот же классика

          Классика
          image

  2. peresada
    /#18886319 / +4

    Linux как воплощение зла
    rm -rf /

    • Leopotam
      /#18886493

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

      • peresada
        /#18886635

        точно, не смог вспомнить наверняка

    • sopov
      /#18886627

      Счастливая девочка… за секунду до…

  3. baldrs
    /#18886451

    У любой технологии есть свои хейтеры, например многие незаслуженно ненавидят PHP.

    • nexus478
      /#18886577

      Настолько ли незаслуженно?

      • rjhdby
        /#18887233

        В целом да

        • nexus478
          /#18887333

          И что вы хотите сказать этой ссылкой? Автор недвусмысленно пишет

          На самом деле с большинством написанного я соглашусь. PHP – противоречив. Многословен. Там действительно есть примеры неадекватного поведения. У него есть много проблем. Порой он уродлив. Иногда он неуклюж в обиходе. Многое оставляет желать лучшего.

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

          • rjhdby
            /#18887369

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

            Мне вот органически неприятно писать на JS, например, но я же не пытаюсь навязать свое мнения тем, кому он нравится. Тогда почему те, кому не нравится PHP, pascal, Java, C#, любой другой язык, позволяют себе выливать на окружающих тонны своей ненависти?

            • Free_ze
              /#18887501

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

              Обижаться на то, что какой-то негодяй ругает твою любимую технологию — это же бестолково и иррационально)

              • rjhdby
                /#18888769

                Пафосное и, зачастую безосновательное, клеймение позором и обсуждение недостатков — это несколько разные вещи.
                Второе, в большинстве случаев, интересно и конструктивно.
                Первое — «бестолково и иррационально» и вызывает чувство, что вляпался во что-то мерзкое.

                • Free_ze
                  /#18889139

                  Одно дело, если вас называют «бестолковым %LANG%шником», совсем другое — если "%LANG% — ни на что не годный микроскоп с интегрированным гвоздодёром". Статейка про «фрактал плохого дизайна» относится как раз ко второй группе, как можно ее считать «клеймением позором» тех, кто этот язык использует — это для меня вопрос. Стыд возникает тогда, когда человек не в силах изменить обстоятельства. Вы ведь, по вашим словам, принимаете критику, но продолжаете использовать язык. Значит на это есть достаточно весомые причины.

                  • rjhdby
                    /#18889497

                    Вот вам прямая цитата

                    И я никогда не встречал PHP-разработчика, который может сделать тоже самое на PHP. Но я натыкался на достаточное количество тех, кто сразу начинает извинятся за что-то и всё, что делает PHP. Такое мышление ужасает.


                    как можно ее считать «клеймением позором» тех, кто этот язык использует — это для меня вопрос

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


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

                    • Free_ze
                      /#18889675

                      Если вы считаете, что это конструктивная критика не переходящая на личности

                      Я считаю, что это личное оценочное суждение о технологии и немного бугурт в сторону фанбоев. Да, конструктива здесь не много, но и поливания грязью огульно всего PHP-сообщества я здесь не вижу.

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

                      Если же вы этим не болеете, тогда я более, чем уверен, что эти «лучи добра» направлены мимо вас.

                      • rjhdby
                        /#18889921

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

                        • Free_ze
                          /#18889947

                          Мне сейчас можно оскорбиться?)

                          • rjhdby
                            /#18890089

                            Мы с вами говорим о разных вещах.

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

                            • Free_ze
                              /#18890161

                              Фактически вы приходите на кулинарный форум, где на одном из стендов рядом новоиспеченный веган вещает о том, что он жил в обмане всю жизнь и возмущается, что эти «мясоеды» мясо любят лишь потому, что ленятся подобрать себе сбалансированный растительный рацион. И… говорите, что вам неприятно это слышать.
                              Но что же вам мешает пройти мимо стенда и не обращать на чудака внимание, как наверняка поступили бы в реальной жизни? Или тут дело во внутреннем конфликте?

                              • rjhdby
                                /#18890205

                                Nope :)
                                Если проследить ветку с самого начала, то в разговоре за способы приготовления стейков, кто-то сказал «да вполне можно на сковороде жарить!» И тут появляется веган.

                                • Free_ze
                                  /#18890315

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

                                  Хм. Эта ветка начинается с троллинга о том, что PHP-могет, а кто считает иначе — не прав. Хотя статья вообще не про PHP. Но о своей любви заявить было нужно. Очевидно, это был вызов на дуэль, который мигом приняли.

                                  • rjhdby
                                    /#18890353

                                    Да вот мне тоже кажется, что самый первый пост писался с целью «выстрелить в толпу». У него получилось.

                            • Free_ze
                              /#18890217

                              попытается объяснить, что на вкус и цвет товарищей нет

                              На вкус и цвет — это ставить "$" перед переменными или табы с пробелами. Но ведь бывают дыры в дизайне, которые бывают вполне объективно хуже реализованы, в сравнении с другими языками.

                              • rjhdby
                                /#18890333

                                Дженерики в Java, макросы в Си, выделение блоков отступами в Python, TMTOWTDI в Perl, в целом JS ;) — для любого языка можно найти спорные реализации/решения.
                                И тянутся они от версии к версии, где-то как груз обратной совместимости, где-то как «фишка языка», оправдываемая только любящими писать на них.

                                Да, изначальный дизайн PHP не то, чтоб хорош, но к его чести можно сказать, что он активно развивается и улучшается. Начиная с 5.6 на нем можно писать хорошо, удобно и быстро, не сталкиваясь в повседневной жизни с 90% того, что описано в хейтерской статье — было бы желание.

                                • Free_ze
                                  /#18890377 / +1

                                  Ну вот те же дженерики джавы и сишарпа — это вкусовщина или все же объективный недостаток дизайна первой? Лучшее, что вам ответит на это джавист: «Потому что это не нужно».

                                  • rjhdby
                                    /#18890549

                                    Бинго!
                                    (сарказм) А еще она многословна, глючна, тормозна, ничего нормально не напишешь без многомегабайтных спрингов и вообще не компилится в нативный код — приходится JVM повсюду таскать.

                                    Собственно единственное, что я пытался донести — это то, что статьи в стиле «Говно! Говно! Роза! Роза? Наверное пахнет как говно! Чтоб вы все сгорели!» — в принципе не могут нести никакого конструктива. И, так долго обсуждаемый нами, текст относится именно к такому типу, к сожалению.

                                    • Free_ze
                                      /#18890617

                                      Вместо того, чтобы смотреть на говно с розами, можно было бы черпать новую информацию об интересующих технологиях)
                                      Люди делятся опытом насчет тонких мест и краевых условий, пишут бенчмарки, кидаются пруфами, лезут в исходники библиотек… Это все абсолютно бесплатно и скорейшим образом, чтобы максимально доходчиво показать, насколько же вы ебобонекомпетентны. Это же прекрасно и одна из главных целей существования хабра.

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

            • nexus478
              /#18887533

              почему те, кому не нравится PHP, pascal, Java, C#, любой другой язык, позволяют себе выливать на окружающих тонны своей ненависти?

              Это уже вопросы к ним, а не ко мне :)

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

              • rjhdby
                /#18888763

                Изначально, таки, речь была про то, что

                У любой технологии есть свои хейтеры

                Вы блестяще подтвердили этот тезис.

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

                • nexus478
                  /#18889289

                  Изначально, таки, речь была про то, что у любой технологии есть свои хейтеры

                  Нет, я комментировал вторую часть того предложения, а именно
                  многие незаслуженно ненавидят PHP.

                  К «незаслуженности» у меня возникли вопросы.

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

                  Если у человека есть неприязнь к инструменту и он её обосновал, то что тут не так?

                  • VolCh
                    /#18889337 / +1

                    Есть разница между «я не могу придумать условия, при которых я бы выбрал инструмент Ч для решения своих задач» и «я ненавижу Х, когда же он сдохнет?!!!»

        • kovalenko_k_i
          /#18889155

          Пацаны — вообще ребята! =) Оба привели статьи 2012 года выпуска, может давайте еще про PHP4 будем говорить, или лучше про то говнецо, что в те далекие года гордно несло название JavaScript? Вы вообще PHP7+ в глаза то хоть видели?

      • rudinandrey
        /#18889149

        >>>> Кстати: я обожаю Python. И с удовольствием прожужжу тебе уши, ноя о нём
        этим все сказано :( вечная борьба Python против PHP, ох уж эти питонисты, что им спокойно не живется, я вот никак не могу понять природу ненависти языка PHP у программистов на Python. P.S. использую оба этих языка в работе.

      • avraam_linkoln
        /#18889153

        оо, статья шестилетней давности. Давайте ещё PHP 3 поругаем

  4. hazratgs
    /#18886501

    О боже, RuVDS как вы могли перевести эту статью, после таких крутых статей?

    • funca
      /#18888191

      «в информатике есть две трудные проблемы: у нас только одна шутка и она не смешная»
      Мне показалось, что статья задумывалась как каламбур типа вредных советов с моралью как избегать запутанного кода. Но по слогу несколько не дотянули до эталонов жанра, получилось скорее глупо нежели зло.

  5. paratagas
    /#18886707 / +3

    Вы извините, конечно, но на разделе «Непростые имена» я уже не выдержал. Неужели вы найдете хоть одного разработчика, который в имя переменной будет подсовывать «какахи» и полноширинные символы вместо обычных, чтобы потом использовать эти имена? Про самоуничтожающиеся объекты через геттеры-сеттеры — это вообще какая извращенная фантазия должна быть?! Так можно дойти до того, что в конструкторах одного класса будем уничтожать произвольные объекты другого класса. Почему нет, Javascript же позволяет. Это нужно поместить в раздел «Ненормальное программирование» и поменять «желтый» заголовок.

    • VolCh
      /#18888685

      киррилица вполне может встретиться в именах. Особенно «с», поскольку на одной клавише с «c» в qwerty/йцукен раскладке.

  6. neurocore
    /#18887183

    К реальным минусам js отнёс бы отсутствие типобезопасности и const-корректности.

    • abyrkov
      /#18887245

      Ну для мелких проектов типобезопастность это не проблема — все держишь в памяти и легко находишь ошибку. Для крупных есть TS и Flowtype.
      const-корректность — это вы про то, что свойства константного объекта можно менять? И правильно, константность не всегда означает иммутабельность.

      ИМХО, отсутствие многопоточности и/или средств кооперативной многозадачности куда большая проблема.

      • neurocore
        /#18887271

        Методы не могут гарантировать неизменность объекта. Не знаю, может это я как адепт Си++ придираюсь. Но отсутствие явного типового соответствия в функциях напрягает, да и неявное приведение типов просто чумовое)

        • abyrkov
          /#18887309

          Методы не могут гарантировать неизменность объекта.
          Это уже к иммутабельности (которую мы можем обеспечить через заморозку и ко).
          отсутствие явного типового соответствия в функциях
          Идите в TS, он вам больше понравится
          неявное приведение типов
          Правила приведения типов не нарушаются, просто это более свободная версия. Минусом это трудно назвать, равно как и плюсом. Скорее, подводный камень.

  7. celebrate
    /#18887999

    Конечно, треш можно написать на любом языке, но некоторые языки словно подталкивают к этому обилием всяких хитрых неочевидных конструкций. Например, раньше писал на Перле, так ведь этот язык просто все время нашептывает тебе на ухо: «Брось писать читабельный код, используй только знаки препинания!»

  8. Sabubu
    /#18888119

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

    > let get = (obj, property, default) => {

    Если бы вы писали определение функции со словом function, оно было бы читабельнее, понятнее (с первого слова понятно, что у нас функция, в случае с let это не так) и точно меньше бы раздражало:

    function get(obj, property, default) { 


    Насколько это чище, аккуратнее, красивее!