Как стать автором
Обновить

Комментарии 52

8. Выкиньте JavaScript и возьмите CoffeeScript, если у вас нет особых причин так не делать.
Ничего не имею против CoffeeScript, но не вижу его преимуществ в рамках обсуждаемой статьи. JS — довольно удобный и функциональный (в двух смыслах) язык.
Быть может, кому-то не хватает «сахара» — пожалуйста, юзайте CoffeeScript.

Но «выкидывать» — не надо, это Вы перебрали.
Статья вроде о том, как человеку малознакомому с JavaScript подойти к разработке вёб-приложений? Так вот для человека до этого программировавшего на других языках в JavaScript слишком много заботливо приготовленных граблей. Я не говорю, что JavaScript плох, но CoffeeScript скорее всего позволит совершать меньше ошибок.
А примеры граблей можно? CoffeeScript не юзаю, в js граблей не встречал, интерес чисто спортивный. :)
Навскиду — весьма необычный подход к this и к области видимости переменных, прототипное наследование.
хммм…
В чем необычности подхода к this? Резиг справедливо подметил, что для начинающих программистов на джаваскрипте не вполне очевидно, что появление «this» в коде функции указывает на то, что перед нами конструктор объекта.

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

Прототипное наследование — ну допустим, а в чем здесь подвох?

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

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

Цитирую: «When Object is called as part of a new expression, it is a constructor that may create an object.», и далее по текстустраница 112

В конце концов не так важно как вы его называете, суть от этого не меняется. Просто в это надо втянуться :)
Про this вы сами ответили. Про область видимости — блоки {...} не создают новый scope. Прототипное наследование как минимум непривычно.

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

Ну и картинка в тему
image
Про this мне просто реально непонятно — что вас смущает?
Отсутствие блочной области видимости — ну такова особенность. Я ни разу не встречал на практике ситуации где необходима блочная область видимости, но если это настолько критично — заверните замыканием, и получите отдельный namespace.
То, что он похож на this в C++ или Java, но при этом ведёт себя по другому — указывает не на тот объект, которому принадлежит функция, а на тот объект, на котором её вызвали. Именно отсюда возникла
    //удобная ссылка на сам объект
    var self = this;
в четвёртом пункте статьи.

Это всё некритичные вещи, «особенности», как вы их назвали. Но именно из таких «особенностей» складывается образ языка программирования. Про них можно знать и к ним можно привыкнуть, но лучше бы их не было.
Это взгляд с вашей колокольни, аналогично для людей прекрасно осознающих это, некоторые вещи в в C++ или Java могут показаться очень странными и неудобными.

Предлагаю приводить явные аргументы, потому что пока я вижу только домыслы.
А я сразу сказал что это взгляд с колокольни С++, Javа, и некоторых других популярных языков. Да и вообще, посмотрите на заглавную картинку поста.

Если вы уже профессионал в JS, то это вполне нормальная причина использовать его, а не CS.
А если вы в JS новичок, но по каким-то причинам вам нужно разработать Web-приложение, то лучше взять CS и сразу начать писать правильный код, а про устройство JS почитать отдельно. Иначе велик шанс, что код придётся неоднократно переписывать по мере узнавания той или иной «особенности» языка.
[mode=troll]
> А если вы в JS новичок, но по каким-то причинам вам нужно разработать Web-приложение
то вы возьмете откуда-нибудь с hotscripts, а если не получится — будете создавать на всех форумах ветки «помогите, я все сделал правильно, а оно не работает, почему?»
[/mode]
Хорошо, здесь требуется уточнение — правильность кода кто оценивать будет? Я вот считаю что я пишу правильный js код, CS посмотрю как-нибудь как время будет :)
Серьезно, какой процент профи и новичков в курсе про кофейскрипт?
С профи — не знаю, думаю, зависит от многих факторов, в основном — от желания изучать новое.
С новичками — как-то очень уверен, что этот процент околонулевой — они просто не слышали «про такую хрень».
Если уж чуть ли не каждый второй думает что js это java, то что уж там про CS говорить :)
Ну вот я здесь про CS написал, может процент новичков и увеличится.
А среди профи процент я думаю и так достаточно высок, всё же без желания изучать новое профессионалом вообще стать трудно.

К тому же, речь идёт не о скриптах типа «хочу что бы кнопка donate сама бегала за курсором», а о web-приложениях. Хочется надеяться, что среди их авторов профессионалов чуть больше чем в среднем по палате.
Пример из недавнего прошлого:
myInstance = new MyClass someArguments...
Случай весьма редкий, но в чистом js превращается в какую-то некрасивую лапшу.
Вообще эта конструкция с многоточием делает немалую часть кода весьма чище.
Также coffeescript вам заботливо завернёт в [""] все зарезервированные слова, от которых всякие мобильные сафари/эксплореры любят падать. Да-да, я именно про эти ваши delete/class/super.
Поможет расставить дефолтные значения принимаемых аргументов, то как
(bar = 42) -> bar + 1
Избавит от этой головной боли с бесконечными slice'ами аргументов.
Правильно подберёт необходимые условия наличия необходимых объектов прямо в выражении:
foo?.bar?.callme()
Также вы забудете про нелепые ошибки связанные с использованием нестрогого оператора сравнения.
Забудете про «случайные» вылезания переменных в глобальный неймспейс.
Получите более-менее приличные классы с приятным объявлением методов прототипа.
Все ваши ошибки с некорректным кодом будут вываливаться на уровне компиляции.
Получение родительского контекста через =>, вместо -> — пусть люди уже забудут про myFunc() {… }.bind(ths)
Нормальная конкатенация не только строк, но и регулярных выражений.
function () {… }.bind(ths)

fxd
>> myInstance = new MyClass someArguments…

Мне такая конструкция незнакома. Подскажите где про нее можно почитать.
Как я уже говорил, проблема начинаний на JavaScript — недопонимание его конструкции, идеологии. Обычно с джаваскриптом знакомятся либо совсем с нуля, либо имея за плечами опыт с процедурными или ООП языками, а js не является ни тем, ни тем. И вот когда пытаются применить в нем понятия, принятые в этих языках, то получается неуклюже, соответственно начинают ругать язык. А особо вопиющая (но, увы, распространенная) ошибка — путать его с Java.

Странно, что мало (или плохо разрекламированы) книг с описанием сильных сторон js, и обучающих правильному подходу. А ведь они весьма красивы:
1. самая краткая форма записи массивов и объектов, известная как JSON — странно, что с этой аббревиатурой ассоциируют только форму записи передачи данных от клиента серверу и обратно, а для самого структурирования данных ею практически не пользуются. И это при том, что так можно записывать не только данные, но и грамотно организовывая код, обеспечивая и инкапсуляцию, и модульность кода.
2. прототипная модель языка — жаль, что это мало о чем намекает. А это же динамическая (почти) типизация. А это значит, что, например, вместо var a = «a»; можно записать var a = function () {return «a»;} и это не повлечет переписывания кода, что было бы неизбежно в статически типизированных языках. Конечно, при таком подходе, на первый взгляд, сложнее контролировать корректность данных — но это только на первый взгляд. А вот если проверять не тип данных, а их наличие, например так: if(typeof a.b != 'undefined') {a.b();} то проблем не возникает.
3. асинхронность языка — во многих языках есть проблема параллельных вычислений или создания потоков. В том же С++ потоки нужно организовывать средствами конкретной ОС, и это печально. В JS мы можем свободно распаллеливать вычисления, и задавать коллбеки по завершении, и это все не выходя за рамки языка. Более того, как и в Java, нужно иметь эту асинхронность ввиду — согласен, это усложняет и написание кода, и чтение.
4. замыкания — функция в JS является объектом, а переменные видны вниз по стеку вызовов, поэтому ими можно оперировать также свободно, как и данными. Жаль, что после Java и иных статически типизированных языков без замыканий ими как-то стесняются, что ли, пользоваться, в то время как это очень мощный и полезный инструмент — я бы сказал, друг программиста.
5. как вывод из всех предыдущих пунктов — на JS отлично уживается функциональная парадигма. Но плюсы ФП, к сожалению, в комментарий не засунешь — просто скажу, что определенный круг задач сразу записывается намного читабельнее.

Я бы вообще JS больше сравнивал с Lua — они наиболее похоже, но почему-то, Lua все любят, а JS обижают.
Не обижают, просто по незнанию недооценивают.
Пример в п.2 какой-то неверный и не имеющий никакого отношения к прототипному наследованию.

Что касается 3, то асинхронность языка вовсе не даёт вам параллельность вычислений. JavaScript однопоточен, а Web workers появились совсем недавно. Да и нет в самом JavaScript особой асинхронности.

Да и с 5 я бы тоже не согласился, к функциональному стилю JS приближает только наличие замыканий, но замыкания сейчас есть в том или ином виде практически везде. Конечно, вы можете писать на JS в функциональном стиле и получать все не описанные вами преимущества, но сам язык этому точно не способствует.
2. согласен, прототипы упомянуты немножко всуе — я говорил про типизацию. А по наследованию, то, грубо говоря, его тоже нет — просто каждый объект держит ссылку на некий объект, называемый прототипом, от которого «автоматически» получает его свойства, но из-за особенностей языка это не совсем то наследование, какое есть в ООП.

3. я, наверное, опять выразился неточно, но асинхронность вполне же есть — возьмем те же XHR запросы.

5. а я и не говорил, что это функциональный язык. вот «вы можете писать на JS в функциональном стиле» — это вы хорошо резюмировали, именно это я и имел ввиду.

— кстати, есть еще один непонятный мне момент — некоторые говорят, что типизация вы JS утиная. Но ведь если мы два объекта произведем от разных прототипов и дополним их до одинакового набора свойств, от этого же они не станут одинаковыми, т.к. прототипы все еще остались оригинальными. Или...?
Утиная? Это потому что если что то ходит как утка, крякает как утка, то это и есть утка? :)
Так точно = )
На самом деле она ещё и плавать как утка должна, если верить английской википедии :-)
3 — это всё библиотеки, а не язык. Местами (например в node.js) асинхронность вообще в абсолют возведена. А асинхронность в языке это например async/await из С#. Или, если говорить о JS, то это например streamline.js.

Что касается «утиной» типизации — язык не заставляет вас сравнивать прототипы или как-то указывать тип объектов, вы просто вызываете методы, или проверяете наличие свойств. Если же вы начнёте в начале каждого метода проверять прототипы объектов, то по сути вы действительно «утиную» типизацию уберёте.
Я говорю про ==.

М, надо поставить эксперимент.
По == они равны не будут даже если вы их от одного прототипа произведёте.
Да, точно.
Кофе помогает не спать, но мыслить не помогает.
НЛО прилетело и опубликовало эту надпись здесь
В 4-ом пункте все корректно.

Смотрим код:
  var doc = new NoteDocument("hello!");
  doc.init();


1. Создается экземпляр NoteDocument — при этом создаются все внутренние функции, включая parse, которая стоит в определении ниже чем init
2. Вызывается init, которая в этот момент уже может обращаться к parse
НЛО прилетело и опубликовало эту надпись здесь
А не для того ли там объявлена переменная var self = this;?
Если внутри parse() используется self, то она будет найдена в цепочке областей видимости.
увы, я вначале не правильно понял вопрос.
да parse не имеет доступа к this.
поэтому там есть ссылка «self», чтобы parse мог обращаться через нее к публичным полям и функциям объекта.
а почему бы вместо

NoteDocument = function(str){

//удобная ссылка на сам объект
var self = this;

//внутреннее поле
var data;

//публичный метод
this.init = function(){
parse(str);
};

//внутренний метод
function parse(str){

}

};

не написать?

var NoteDocument = {
init: function() {
parse(str);
}

parse = function(str) {
//…
}
};
Вот блин, даже исходник не могу выделить тэгом.
Да, можно выбрать много способов записи. Это же Js. :)
Я выбрал тот, что больше всего напоминает Java код
Немногие знают, что кривой код может вызвать лаги в браузере
а бывает, и падение — это к недавней статье о ИЕ6.

в 90х был прикольный «вирус», точнее DoSник на жабаскрипте, который открывал себя в новом окне, пожирая ресурсы компа.Малвар, а код корректный.
Кстати, если уж зашла речь о хороших IDE — хотел бы упомянуть Visual Studio с ReSharper'ом, вдруг кто не знает. Решение, конечно, не бесплатное, но для рабочего человека стоит недорого. Зато будет всё на свете: и IDE высшего уровня, и интелисенс (включая jQuery), и встроенный дебаг JS прямо в студии, используя IE (очень удобно микшировать серверные и клиентские точки останова)… и вообще всё то, чем богата VS.
а почему все молчат про Idea?
как само собой разумеющееся, да?

на самом деле, у нее лучше всего автокомплит работает с этим языком — это не реклама, а свой горький js-опыт (камень в сторону Eclipse)
Как это молчат? Автор её первой упомянул в статье :-)
Ой, пардон, точно — ее не выделили гиперссылкой, поэтому упустил.
Если начали обращать внимание на подобные вещи, то думаю стоит обратить внимание на новую книгу Maintainable JavaScript автора Nicholas C. Zakas.
Спасибо за рекомендацию!
Может, есть перевод на русский? Проще впитывать инфу на родном языке.
Врядли, книга довольно новая, а проще не всегда значит лучше :) На самом деле технические книги не пишутся сложным английским, особого труда составить не должно, плюс повод потренировать английский. Когда-то ведь нужно будет начинать осваивать английский, так почему не сейчас :)

Если что вот эти тоже могут быть полезны (перевод некоторых возможно существуют):
[2008] JavaScript. The Good Parts (Oreilly) Douglas Crockford
[2008] Object-Oriented JavaScript (Packtpub) Stoyan Stefanov
[2010] High Performance JavaScript (Oreilly) Nicholas C. Zakas
[2010] JavaScript Patterns (Oreilly) Stoyan Stefanov
Спасибо.

Нет, с английским лично у меня проблем нет )
>> Нет, с английским лично у меня проблем нет )
А я и не утверждал что они есть :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации