JavaScript Garden на русском языке — Готов! перевод

Стараниями четырёх людей мы перевели JavaScript Garden на русский язык!

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

Поскольку это слишком крупный перевод и хабр вряд ли осилит его со всеми исходными кодами, придётся просто дать вам ссылку: [JavaScript Гарден на русском].



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

Весь перевод производится в соответствующем github-репозитории, так что если вы хотите помогать — you're welcome.

P.S. Когда авторы вольют перевод к себе на сайт, если примут, он будет также располагаться где-то здесь, но всё равно обновлять его мы будем чаще по ссылке из поста.
+231
21 марта 2011, 12:24
287

комментарии (52)

+17
great_boba #
Молодцы
+2
spmbt #
Ценное руководство, если всё там будет (или есть) доходчиво и без тумана.
Но вот что сразу заметил:

Единственный способ удалить свойство у объекта — использовать оператор delete;
устанавливая свойство в undefined или null, вы удаляете только связанное с ним значение, но не ключ.

Наверное, «Вы меняете», а не «Вы удаляете». (undefined или null — такое же равноправное значение, как строка, ссылка или объект)
+2
alisey #
Нет, связанное значение не меняется. Оно именно удаляется (точнее удаляется ссылка на него, и если ссылок больше нет, то удаляется и само значение сборщиком мусора).
0
donnerjack13589 #
Обычно не рекомендуется использовать delete, так как performance cost достаточно велик (из-за вызова GC)
0
zokotuhaFly #
Согласен, справедливо. Хотя в исходнике — «removing».

Тогда правильнее будет "… устанавливая свойство… вы просто меняете его значение, но ни ключ ни значение при этом не удаляются". Соберём пяток таких правок и обновим.
+1
zokotuhaFly #
хм. нет, послушаюсь alisey :)
+1
spmbt #
Это я привёл как пример небольшого «тумана». Можно и так сказать, и так. И alisey сказал, что есть случаи, когда значение не удаляется. А в фразе надо было сказать, что некто хотел удалить ключ. Написал «obj.value = undefined;». B далее нужно подчеркнуть, что он мог ничего не удалить — ни ключ, ни значение. Я бы написал:

устанавливая свойство в undefined или null, вы только заменяете связанное с ним значение, но не удаляете ключ.


И дальше можно: «Если ссылок на значение больше нет, то удаляется и само значение сборщиком мусора, но ключ объекта остаётся с новым значением.», но это уже не суть.
+1
alisey #
Да, так было бы отлично. Заменяете значение — самый правильный вариант.
+2
alisey #
При переводе нужно быть ооочень аккуратным, чтобы избежать не только стилитических ошибок вроде «двух очаровательных пользователей StackOverflow», но и смысловых ошибок:

Оригинал:
"[Prototypical inheritance] It is for example fairly trivial to build a classic model on top of it, while the other way around is a far more difficult task".

Перевод:
"[Прототипная модель наследования] К примеру, поверх неё можно предельно легко реализовать классическое наследование, а попытки обойти его при этом могут создать только трудности."

Хотя на самом деле смысл такой:
"[Прототипная модель наследования] К примеру, на ее основе достаточно легко построить классическую модель, в то время как обратная задача куда сложнее."

Важно отдавать себе отчет, понимаешь ли сам, что написано. Если не понимаешь — не надо браться. Если понимаешь, но предложение никак не клеится — объясни своими словами.
+2
AntonShevchuk #
Есть некоторые ньюансы конечно, и еще ошибки при мерже ;)
К примеру, с ее помощью можно легко реализовать классическое наследование, а наоборот — тут уж придется сильно потрудиться.
+2
zokotuhaFly #
AntonShevchuk правильно перевёл в обоих случаях, а я исправил. Но объясните тогда, что имеется ввиду под «обратной задачей». Реализация не-классического наследования? Реализация классического наследования наоборот?.. Хм… теперь я понял, да.

Это обновляющаяся статья, вы можете вносить правки. Она для этого и придумана, чтобы её со временем исправляли и делали лучше. Иначе бы русского перевода не было бы вообще.

Ищите ещё ошибки, пожалуйста, они будут исправлены благодаря вам.
0
zokotuhaFly #
Вы есть на гитхабе и я добавил вас в коммитеров — так что флаг вам в руки :)
+1
zokotuhaFly #
залил все исправления от alisey, spmbt и donnerjack13589
+1
donnerjack13589 #
У вас там в одном месте используется:

{}.hasOwnProperty


Поправьте, пожалуйста!
0
zokotuhaFly #
Так и должно быть: это обход на случай, если есть подозрения на то, что метод hasOwnProperty могли переопределить
+1
donnerjack13589 #
Так то оно так :)
Только вот правильно будет:
({}).hasOwnProperty


Иначе ошибка!
+1
azproduction #
А если поставить {}.hasOwnProperty в состояние выражения, то ошибки не будет ;)
var a = {}.hasOwnProperty;
a.call({a:1}, 'a');
0
donnerjack13589 #
Ну если бы в доке было так, я бы не писал ;)
0
zokotuhaFly #
Да, ваша правда. Пошёл писать авторам.
+1
zokotuhaFly #
Пофиксили и в оригинале и в переводе
+5
kliss #
При всем уважении к труду авторов, перевод технической документации на русский — самое бессмысленное в мире занятие. Воду в решете носить и то имеет больше смысла.

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

Кто не хочет учить английский — пусть идёт дисками на рынке торговать. Такое моё мнение.
+11
TheShock #
Я владею английским, но мне приятно читать на русском.
Не всё такое чёрно-белое, как описано в вашем сообщении. Нельзя или владеть английским или не владеть. Это только в резюме такие формулировки годятся.
–3
kliss #
Мне приятнее читать то, что хотел донести до меня автор. А не «двух очаровательных пользователей StackOverflow»
0
zokotuhaFly #
уже исправили «очаровательных». а как бы вы «lovely» перевели?
+3
AntonShevchuk #
вариант:
Это руководство создано двумя замечательными пользователями Stack Overflow: Ivo Wetzel (сочинял) и Zhang Yi Jiang (рисовал).


P.S. Куда лучше быть автором перевода, чем кичится знанием английского в комментах к переводу, так что хватит кормить этого троля
0
zokotuhaFly #
Там просто чуть выше "… ознакомьтесь с замечательным руководством на сайте Mozilla Developer Network.". хотя дальше по статье некоторые фразы надо всё-таки литературно править. Вчера ночью казалось вполне читаемо, а сегодня некоторые отдельные фразы на русском выносят мозг.

Нужно чтобы кто-то осмелился и зарегался коммитить ради стилистических правок, занялся редактурой. Пусть даже это будет тролль, если качественно будет делать :)
0
kliss #
В этом и суть проблемы, что переводить слова — это не числа в другую систему переводить.
С каждым идет в нагрузку ворох смысловых нагрузок и образов.

Некоторые слова так и вообще перевести нельзя, потому что у нас нет таких понятий/образов.

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

Касаемо вопроса: в данном случае слово «lovely» несет (для меня) смыслы «ценный» и (чуть меньше) «хороший, приятный».
0
zokotuhaFly #
Ну тогда отпишитесь от блогов «перевод», что вы прямо. Или welcome в качестве корректора. Дискуссию действительно бесполезно разворачивать, таких обуждений кучи по интернетам ещё с конца 90-х.
+1
kliss #
Да я в гуглоридере читаю. Этот пост там засветился :-) Дискуссию разводить и впрям бесполезно :-)
+3
TheShock #
Мне приятнее читать то, что хотел донести до меня автор

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

Я читал JSGarden в оригинале, для меня там не было ничего нового, но теперь рад, что есть перевод. Это — хорошо.
+1
BuCeFaL #
Не хорошо, как то, указывать людям что и как им делать (если вы за это не платите). А владеть английским языком можно на разных уровнях- у кого то он меньше, у кого то больше. А уровень професионализма программиста показывают реализованые им задачи, а не знание англ.языка. Хотя знание англ. языка влияют на возможность реализовать ту или иную задачу, но все «важнее всего результат».

+1
xappymah #
Слишком уж категоричное заявление.
Все-таки чтение на чужом языке напрягает и утомляет гораздо сильнее, чем на родном.

(Кстати, перевод технической документации — это еще и огромный вклад в копилку собственного знания языка)
0
kliss #
> Все-таки чтение на чужом языке напрягает и утомляет гораздо сильнее, чем на родном.

Да, это так, но только до определенного уровня. Где-то дальше есть ступень, когда ты прочитаешь текст, а потом даже затрудняешься сказать, был он на русском или иностранном.

> (Кстати, перевод технической документации — это еще и огромный вклад в копилку собственного знания языка)
Может быть. Но художественная всяко полезнее в этом плане.
+1
depp #
Многие моменты освещены очень грубо, поверхностно, а местами — явно некорректно.
Например, почти сразу бросается в глаза фраза на shamansir.github.com/JavaScript-Garden/#object.general
«В JavaScript всё является объектом, лишь за двумя исключениями — null и undefined.», которая является весьма популярным заблуждением. В языке есть примитивы строк, чисел и булевых значений, и они не являются объектами ни в каком смысле, кроме того что определенные виды объектов могут образовываться из таких типов динамически, ради возможности вызова методов вроде 'abc'.toUpperCase().

Понимаю, что перевод, но надо ж смотреть, что переводишь.
+1
tenshi #
докажи, что числа и строки не являются объектами.
афайк, они обладают состоянием и поддерживают вызов методов. механизм этой поддержки — детали реализации.
0
depp #
Основное свойство объекта в JS — наличие собственных свойств, возможность их добавлять и изменять.

Попробуй добавь к строке или числу какое-нибудь свойство и попробуй его потом прочесть )
Сразу станет понятно, где объект, а где — нет.
+1
Beresta #
var s1 = "abcdefg";
console.log(typeof s1); // "string"
s1.someProp = "abc";
console.log(s1.someProp); // undefined

var s2 = new String("abcdefg");
console.log(typeof s2); // "object"
s2.someProp = "abc";
console.log(s2.someProp); // "abc"


Сойдет? :)
0
tenshi #
console.log(typeof null); // «object»

window.window= {};
console.log(window.window); // «DOMWindow»

и чо? х)
+3
Beresta #
Из стандарта ECMA-262:

Подраздел 4.3 Definitions:

primitive value
member of one of the types Undefined, Null, Boolean, Number, or String as defined in Clause 8.
NOTE A primitive value is a datum that is represented directly at the lowest level of the language implementation.

object
member of the type Object.
NOTE An object is a collection of properties and has a single prototype object. The prototype may be the null value

Оглавление:

8 Types
8.1 The Undefined Type
8.2 The Null Type
8.3 The Boolean
8.4 The String Type
8.5 The Number Type
8.6 The Object Type

Этого тоже не достаточно для доказательства того, что строки и числа не являются объектами?
+2
tenshi #
это их локальная терминология. объект — это гораздо более широкое понятие.
–1
Krovosos #
«В JavaScript всё является объектом, лишь за двумя исключениями — null и undefined.»

1) null — это объект, что легко проверить: typeof(null) выдает «object».

Другое дело, что это специальный объект…

2) числа и строки не являются объектами.

Это также очень легко проверить: typeof(123) выдает «number».
Другое дело, что язык автоматически делает упаковку литерала в объект, если необходимо.

"// валидный JavaScript и валидный JSON
{
'foo': 'oof',
'bar': 'rab'
}"

3) Это _невалидный_ JSON.

+3
depp #
null — это не объект, и даже не специальный объект. это просто тип данных null
оператор typeof не выдает корректный тип объекта во многих случаях (не только с null), это общеизвестный факт
0
zokotuhaFly #
… и он тоже описан в статье

JSON исправил
0
depp #
Лучше б вы не давали эту ссылку, т.к. там тоже материал подан весьма странно :)

Приведенная таблица результатов typeof абсолютно логична и последовательна (ну разве что за исключением typeof new Function("") == 'function' и typeof null == 'object'), т.к. new Number(), new RegExp(), new Object() и т.п. — это все данные типа object, и приведенные выражения ничем не отличаются от new MyFooBar(), например.

Люди, которые пишут про это в том ключе, что мол «это все нелогично, поломано и фиг знает почему так» — банально не понимают, о чем говорят.
+1
zokotuhaFly #
Ну, авторы скорее советуют на это не рассчитывать. И да, они много драматизируют, мы это отметили в примечании от переводчиков. Но некоторые вещи при этом объяснены довольно подробно и понятно. Некоторых начинающих программистов только таким образом и можно приучить следить за своим кодом, через «нельзя», «опасно» и «не делайте так никогда».
0
hiway #
Огромное Вам спасибо!
+1
fls_welvet #
Добавьте, пожалуйста, favicon на сайт. Очень уж некрасиво смотрится в Закладках без неё.
0
spmbt #
Сделал юзерстиль светлых тонов для этой чёрной страницы.
@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document url("http://shamansir.github.com/JavaScript-Garden/") {

body{background: #fff!important; color: #000!important; font-family: Verdana, Helvetica, Arial!important}
nav a code,
.pun{color: #457!important;}
.typ,
.pln{color: #941!important;}
.lit{color: #457!important;}
.com{color: #494!important;}
.kwd{color: #622!important;}
.str{color: #666!important;}
section pre code,
code,
pre{background: #e6e6e6!important;}
pre{border-left: 2px solid #ccc!important;}
section pre code{border: 0!important;}
h2, h3{text-shadow: 0 0 0 #000!important}
article a{color: #c30!important;}
}

Не идеально, конечно, но читать можно.
(Подскажите, где есть готовая светлая цветовая схема?)
+1
backinblack #
Спасибо всей команде, которая трудилась над русским огородом!
Очень порадовали.
0
qnikst #
Возможно я чего-то не понимаю, но стандарт ECMA явно указывает на существование примитивных типов: Undefined, Null, Numeric, String, Boolean, Object. И если иметь ввиду под словом «объект» Object, то тогда утверждение, что всё является объектом неверно.

Да, автоматическое заворачивание примитивного типа в объект никто не отменял.
+1
binariti #
Основная проблема с вашим переводом в том, что на русский язык переведены слова, но не предложения. Из за этого читать очень сложно — приходится продираться через текст не только в смысле понимания материала, но и в смысле понимания того, что там вообще написано. Первая часть текста переведена более менее нормально, вторая — хуже.

1. Хотя большинство из примеров ниже наполнены глубоким смыслом, первый из них можно считать ещё одним упущением в самом языке, поскольку он вообще не имеет практического применения. / Большинство из примеров ниже вполне жизнеспособны, однако первый следует считать ещё одним упущением в самом языке, поскольку он вообще не имеет практического применения.
2. Повторимся, это вообще не тот же самый эффект. Если вы не используете var — то вы в большой опасности. / Again, that is not at all the same effect, not using var can have major implications. – И еще раз – опуская var, вы создаете сильную путаницу, поскольку это не приводит к тому же самому результату.
3. Высасывание / Hosting – по смыслу «выталкивание»
4. Безымянные функции являются выражениями; поэтому, чтобы вы имели возможность их выполнить, они сперва должны быть разобраны / evaluated – вычислены. Или это специальный термин?
5. позваоляет создавать более модульные программы / «позваоляет» — опечатка / it also allows for better modularization of programs / позволяет лучше спланировать структуру кода
6. нет достаточных оснований для использования цикла for in для итерации по элементам массива. Фактически, существует несколько весомых причин против использования for in в массивах. / вообще очень сложно читается, лучше – Не смотря на то, что массивы это объекты, обычно не имеет особого смысла использовать для них цикл for in. Более того, существует ряд причин против применения for in в массивах
7. Единственный способ исключить ненужные свойства — использовать hasOwnProperty, а это в 20 раз медленнее обычного цикла for. / Вообще неверно переведено. Почему это использовать hasOwnProperty – медленнее? Нет, тут имелось ввиду вот что: / Поскольку for in перебирает все свойства в цепочке прототипов, а единственный способ исключить эти свойства – использование hasOwnProperty, то это до 20-и раз медленнее, нежели простой for.
8. Конечно, «синтаксис литеральной нотации» звучит круто, но нихрена не понятно. / объявляя новые массивы рекомендовано всегда использовать массивы-литералы при помощи конструкции [] / и вообще, «литералы» это хорошо, но ведь «константы» — понятнее.
9. заполненный случайными значениями / sparse array это попросту разреженный массив, т.е. такой, где для каждого элемента выделена память, фактически он будет заполнен не случайными значениями, а значениями undefined
10. таких как повторение строк / почему строк, если в оригинале «повторение строки»?
11. сравнения значений объектов на равенство / просто – «два способа сравнить значения объектов»
12. подразумевает приведение обеих переменных к одному типу для того, чтобы произвести сравнение. / в оригинале проще написано – «JavaScript использует слабую типизацию. Это значит, что оператор сравнения выполняет приведение типов для того чтобы сравнить значения»
13. поломан более чем полностью / практически непригоден для использования
14. В примере выше Object.prototype.toString вызывается со значением this, являющимся объектом, значение [[Class]] которого нужно получить. / Фактически toString вызывается таким образом, что значение this внутри нее будет позаимствовано у того объекта, чей класс мы хотим узнать. (это предложение мне показалось сложным для понимания)
15. они могут отличаться в различных реализациях / thus, they can differ across various implementations / могут различаться в зависимости от способа использования. (мне кажется речь идет не о вариантах реализации компилятора, а о вариантах использования typeof)
16. из-за слабости типизации JavaScript / из-за того, что в JavaScript используется слабая типизация
17. приведет к еще большему насилию над типами. / Type coercion is a somewhat ugly looking term which refers to a PostgreSQL method for changing a value from one data type to another. / In addition, having literals or non-object values in there will result in even more type coercion. = Кроме того, использование литералов или необъектных значений [в этих конструкторах] вызовет еще больше преобразований типов.
18. Нативности / Core / может быть просто «Ядро»?
19. 99.9% случаев её «использования» могут достигаться без её участия. / 99.9% of its «uses» can be achieved without it. / В 99.9% случаев тех же результатов можно достичь и без ее применения.
20. eval под прикрытием. …поскольку eval в этом случае вызывается не напрямую. / Неявный eval. …хотя eval и не вызывается напрямую. (since == seeing that)
21. Если вдруг для работы вам необходим eval, эта часть должна тут же ставиться под сомнение и не должна использоваться в первую очередь / Если что-то требует использования eval, следует поставить под сомнение такой способ реализации и не использовать его на первых порах.
22. Параметры, которые не были переданы в функцию явно. / т.е. в тех случаях, когда в функцию не был передан параметр, описанный в ее определении (тут предложение выбивается из текста, но не потому, что неверно переведено, а потому, что каждый элемент перечисления должен отвечать не на вопрос «что?», а на вопрос «когда?»
23. При доступе ко всему, чьим значением является undefined. / Если чему-то уже присвоено значение undefined
24. Парсер радикально подменил поведение / парсер кардинально изменил поведение (вообще слова «радикально» и «драматично» нужно использовать в русском языке с опаской – они не применяются у нас в тех случаях, где в английском языке их можно применять)
25. В то время, когда исполняющийся код будет блокироваться во время вызова с таймаутом, setInterval будет продолжать планировать последующие вызовы переданной функции. Это может (особенно в случае небольших интервалов) повлечь за собой выстраивание вызовов функций в очередь. / Пока выполняемый код блокирует следующий вызов по таймауту, setInterval продолжит генерировать вызовы указанной функции. Это может (особенно в случае небольших интервалов) привести к тому, что вызовы функции выстроятся один за другим, т.е. вовсе без временного интервала между вызовами.
26. Кроме того, избегайте использования setInterval в случаях, когда его планировщик может блокировать выполнение JavaScript. / Кроме того, избегайте использования setInterval, поскольку его планировщик не блокируется выполняемым кодом.
0
zokotuhaFly #
Огромное спасибо за подробный(-нейший) комментарий! Я пересмотрю все пункты и поправлю то, с чем не найду противоречий :). А ещё лучше, если вы зарегитрируетесь на гитхабе и подготовите нам коммит с этими исправлениями.

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