diff options
-rw-r--r-- | ru-ru/javascript-ru.html.markdown | 543 |
1 files changed, 543 insertions, 0 deletions
diff --git a/ru-ru/javascript-ru.html.markdown b/ru-ru/javascript-ru.html.markdown new file mode 100644 index 00000000..ad66b501 --- /dev/null +++ b/ru-ru/javascript-ru.html.markdown @@ -0,0 +1,543 @@ +--- +language: javascript +contributors: + - ["Adam Brenecki", "http://adam.brenecki.id.au"] + - ["Ariel Krakowski", "http://www.learneroo.com"] +translators: + - ["Maxim Koretskiy", "http://github.com/maximkoretskiy"] +filename: javascript-ru.js +lang: ru-ru +--- + +Javascript был разработан Бренданом Айком из Netcape в 1995. Изначально +предполагалось, что он станет простым вариантом скриптового языка для сайтов, +дополняющий к Java, который бы в свою очередь использовался для более сложных +web-приложений. Но тонкая интегрированность javascript с web-страницей и +встроенная поддержка в браузерах привели к тому, чтобы он стал более +распространен в frontend-разработке, чем Java. + +Использование JavaScript не ограничивается браузерами. Проект Node.js, +предоставляющий независимую среду выполнения на движке Google Chrome V8 +JavaScript, становится все более популярным. + +Обратная связь важна и нужна! Вы можете написаться мне +на [@adambrenecki](https://twitter.com/adambrenecki) или +[adam@brenecki.id.au](mailto:adam@brenecki.id.au). + +```js +// Комментарии оформляются как в C. +// Однострочнные коментарии начинаются с двух слешей, +/* а многострочные с слеша и звездочки + и заканчиваются звездочеий и слешом */ + +// Выражения разделяются с помощью ; +doStuff(); + +// ... но этого можно и не делать, разделители подставляются автоматически +// после перехода на новую строку за исключением особых случаев +doStuff() + +// Это может приводить к непредсказуемому результату и поэтому мы будем +// использовать разделители в этом туре. +// Because those cases can cause unexpected results, we'll keep on using +// semicolons in this guide. + +/////////////////////////////////// +// 1. Числа, Строки и Операторы +// 1. Numbers, Strings and Operators + +// В Javasript всего 1 числовой тип - 64-битное число с плавающей точкой +// стандарта IEEE 754) +// Числа имеют 52-битную мантиссу, чего достаточно для хранения хранения целых +// чисел до 9✕10¹⁵ приблизительно. +3; // = 3 +1.5; // = 1.5 + +// В основном базовая арифметика работает предсказуемо +1 + 1; // = 2 +.1 + .2; // = 0.30000000000000004 +8 - 1; // = 7 +10 * 2; // = 20 +35 / 5; // = 7 + +// Включая нецелочисленное деление +5 / 2; // = 2.5 + +// Двоичные операции тоже есть. Если применить двоичную операцию к float-числу, +// оно будет приведено к 32-битному целому со знаком. +1 << 2; // = 4 + +// (todo:перевести) +// Приоритет выполнения операций можно менять с помощью скобок. +(1 + 3) * 2; // = 8 + +// Есть три особых не реальных числовых значения: +Infinity; // допустим, результат операции 1/0 +-Infinity; // допустим, результат операции -1/0 +NaN; // допустим, результат операции 0/0 + +// Так же есть тип булевых данных. +true; +false; + +// Строки создаются с помощью ' или ". +'abc'; +"Hello, world"; + +// Оператор ! означает отрицание +!true; // = false +!false; // = true + +// Равество это === +1 === 1; // = true +2 === 1; // = false + +// Неравенство это !== +1 !== 1; // = false +2 !== 1; // = true + +// Еще сравнения +1 < 10; // = true +1 > 10; // = false +2 <= 2; // = true +2 >= 2; // = true + +// Строки складываются с помощью + +"Hello " + "world!"; // = "Hello world!" + +// и сравниваются с помощью < и > +"a" < "b"; // = true + +// Приведение типов выполняется при сравнении с ==... +"5" == 5; // = true +null == undefined; // = true + +// ...в отличие от === +"5" === 5; // = false +null === undefined; // = false + +// Для доступа к конкретному символу строки используйте charAt +"This is a string".charAt(0); // = 'T' + +// ... или используйте substring для получения подстроки +"Hello world".substring(0, 5); // = "Hello" + +// length(длина) - свойство, не используйте () +"Hello".length; // = 5 + +// Есть null и undefined +null; // используется что бы указать явно, что значения нет +undefined; // испрользуется чтобы показать, что значения не было установлено + // собственно, undefined так и переводится + +// false, null, undefined, NaN, 0 и "" являются falsy-значениями(при приведении +// в булеву типу становятся false) +// Обратите внимание что 0 приводится к false, а "0" к true, +// не смотря на то, что "0"==0 + +/////////////////////////////////// +// 2. Переменные, массивы и объекты + +// Переменные объявляются ключевым словом var. Javascript динамически +// типизируемый, так что указывать тип не нужно. +// Присвоение значения описывается с помощью оператора = +var someVar = 5; + +// если не указать ключевого слова var, ошибки не будет... +someOtherVar = 10; + +// ...но переменная будет создана в глобальном контексте, в не области +// видимости, в которой она была объявлена. + +// Переменные объявленные без присвоения значения, содержать undefined +var someThirdVar; // = undefined + +// Для математических операций над переменными есть короткая запись: +someVar += 5; // тоже что someVar = someVar + 5; someVar равно 10 теперь +someVar *= 10; // а теперь -- 100 + +// еще более короткая запись для добавления и вычитания 1 +someVar++; // теперь someVar равно 101 +someVar--; // обратно к 100 + +// Массивы -- упорядоченные списки значений любых типов. +var myArray = ["Hello", 45, true]; + +// Для доступу к элементам массивов используйте квадратные скобки. +// Индексы массивов начинаются с 0 +myArray[1]; // = 45 + +// Массивы мутабельны(изменяемы) и имеют переменную длину. +myArray.push("World"); // добавить элемент +myArray.length; // = 4 + +// Добавить или изменить значение по конкретному индексу +myArray[3] = "Hello"; + +// Объекты javascript похожи на dictionary или map из других языков +// программирования. Это неупорядочнные коллекции пар ключ-значение. +var myObj = {key1: "Hello", key2: "World"}; + +// Ключи -- это строки, но кавычки не требуются если названия явлюятся +// корректными javascript идентификаторами. Значения могут быть любого типа. +var myObj = {myKey: "myValue", "my other key": 4}; + +// Доступ к атрибту объекта можно получить с помощью квадратных скобок +myObj["my other key"]; // = 4 + +// ... или используя точечную нотацию, при условии что ключ является +// корректным идентификатором. +myObj.myKey; // = "myValue" + +// Объекты мутабельны. В существуюещем объекте можно изменить значние +// или добавить новый атрибут. +myObj.myThirdKey = true; + +// При попытке доступа к атрибуту, который до этого не был создан, будет +// возвращен undefined +myObj.myFourthKey; // = undefined + +/////////////////////////////////// +// 3. Логика и Управляющие структуры + +// Синтаксис управляющих структур очень похож на его реализацию в Java. + +// if работает так как вы ожидаете. +var count = 1; +if (count == 3){ + // выполнится, если значение count равно 3 +} else if (count == 4){ + // выполнится, если значение count равно 4 +} else { + // выполнится, если значение count не будет равно ни 3 ни 4 +} + +// Поведение while тоже вполне предсказуемо +while (true){ + // Бесконечный цикл +} + +// Циклы do-while похожи на while, но они всегда выполняются хотябы 1 раз. +// Do-while loops are like while loops, except they always run at least once. +var input +do { + input = getInput(); +} while (!isValid(input)) + +// Цикл for такой же как в C и Java: +// инициализация; условие продолжения; итерация +for (var i = 0; i < 5; i++){ + // выполнится 5 раз +} + +// && - логическое и, || - логическое или +if (house.size == "big" && house.color == "blue"){ + house.contains = "bear"; +} +if (color == "red" || color == "blue"){ + // если цвет или красный или синий +} + +// && и || удобны для установки значений по умолчанию. +// && and || "short circuit", which is useful for setting default values. +var name = otherName || "default"; + +// выражение switch проверяет равество с помощью === +// используйте 'break' после каждого case, +// иначе помимо правильного case выполнятся и все последующие. +grade = '4'; // оценка +switch (grade) { + case '5': + console.log("Великолепно"); + break; + case '4': + console.log("Неплохо"); + break; + case '3': + console.log("Можно и лучше"); + break; + default: + console.log("Да уж."); + break; +} + + +/////////////////////////////////// +// 4. Функции, Область видимости и Замыкания + +// Функции в JavaScript объявляются с помощью ключевого слова function. +function myFunction(thing){ + return thing.toUpperCase(); // приведение к верхнему регистру +} +myFunction("foo"); // = "FOO" + +// Помните, что значение, которое должно быть возкращено должно начинаться +// на той же строке, где расположено ключевое слово 'return'. В противном случае +// будет возвращено undefined. Такое поведения объясняется автоматической +// вставкой разделителей ';'. Помните этот факт, если используете +// BSD стиль оформления кода. +// Note that the value to be returned must start on the same line as the +// 'return' keyword, otherwise you'll always return 'undefined' due to +// automatic semicolon insertion. Watch out for this when using Allman style. +function myFunction() +{ + return // <- разделитель автоматически будет вставлен здесь + { + thisIsAn: 'object literal' + } +} +myFunction(); // = undefined + +// Функции в JavaScript являются объектами, поэтому их можно назначить в +// переменные с разными названиями и передавать в другие функции, как аргументы, +// на пример, при указании обработчика события. +function myFunction(){ + // этот фрагмент кода будет вызван через 5 секунд +} +setTimeout(myFunction, 5000); +// Обратите внимание, что setTimeout не является частью языка, однако он +// доступен в API браузеров и Node.js. + +// Объект функции на самом деле не обязательно объявлять с именем - можно +// создать анонимную функцию прямо в аргументах другой функции. +setTimeout(function(){ + // этот фрагмент кода будет вызван через 5 секунд +}, 5000); + +// В JavaScript есть области видимости. У функций есть собственные области +// видимости, у других блоков их нет. +if (true){ + var i = 5; +} +i; // = 5, а не undefined, как это было бы в языке, создающем + // области видисти для блоков кода + +// Это привело к появлению паттерна общего назначения "immediately-executing +// anonymous functions" (сразу выполняющиеся анонимные функции), который +// позволяет предотвратить запись временных переменных в общую облать видимости. +(function(){ + var temporary = 5; + // Для доступа к глобальной области видимости можно использовать запись в + // некоторый 'глобальный объект', для браузеров это 'window'. Глобальный + // объект может называться по-разному в небраузерных средах, таких Node.js. + window.permanent = 10; +})(); +temporary; // вызывает исключение ReferenceError +permanent; // = 10 + +// Одной из сильных сторон JavaScript являются замыкания. Если функция +// объявлена в внутри другой функции, внутренняя функция имеет доступ ко всем +// переменным внешней функции, даже после того, как внешняя функции завершила +// свое выполнение. +function sayHelloInFiveSeconds(name){ + var prompt = "Привет, " + name + "!"; + // Внутренние функции помещаются в локальную область видимости, как-будто + // они объявлены с ключевым словом 'var'. + function inner(){ + alert(prompt); + } + setTimeout(inner, 5000); + // setTimeout является асинхроннной, и поэтому функция sayHelloInFiveSeconds + // завершит свое выполнение сразу и setTimeout вызовет inner позже. + // Однако, так как inner "закрыта внутри" или "замкнута в" + // sayHelloInFiveSeconds, inner все еще будет иметь доступ к переменной + // prompt, когда будет вызвана. +} +sayHelloInFiveSeconds("Вася"); // откроет модальное окно с сообщением + // "Привет, Вася" по истечении 5 секунд. + + +/////////////////////////////////// +// 5. Немного еще об Объектах. Конструкторы и Прототипы + +// Объекты могут содержать функции +var myObj = { + myFunc: function(){ + return "Hello world!"; + } +}; +myObj.myFunc(); // = "Hello world!" + +// Когда функции прикрепленные к объекту вызываются, они могут получить доступ +// к данным объекта, ипользуя ключевое слово this. +myObj = { + myString: "Hello world!", + myFunc: function(){ + return this.myString; + } +}; +myObj.myFunc(); // = "Hello world!" + +// Содержание this определяется исходя из того, как была вызвана функция, а +// не места её определения. По этой причине наша функция не будет работать вне +// контекста объекта. +var myFunc = myObj.myFunc; +myFunc(); // = undefined + +// И напротив, функция может быть присвоена объекту и получить доступ к нему +// через this, даже если она не была прикреплена к объекту в момент её создания. +var myOtherFunc = function(){ + return this.myString.toUpperCase(); +} +myObj.myOtherFunc = myOtherFunc; +myObj.myOtherFunc(); // = "HELLO WORLD!" + +// Также можно указать контекс выполнения фунции с помощью 'call' или 'apply'. +var anotherFunc = function(s){ + return this.myString + s; +} +anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!" + +// Функция 'apply' очень похожа, но принимает массив со списком аргументов. + +anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!" + +// Это может быть удобно, когда работаешь с фунцией принимающей на вход +// последовательность аргументов и нужно передать их в виде массива. + +Math.min(42, 6, 27); // = 6 +Math.min([42, 6, 27]); // = NaN (uh-oh!) +Math.min.apply(Math, [42, 6, 27]); // = 6 + +// Однако, 'call' и 'apply' не имеют постоянного эффекта. Если вы хотите +// зафиксировать контекст для функции, используйте bind. + +var boundFunc = anotherFunc.bind(myObj); +boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!" + +// bind также можно использовать чтобы частично передать аргументы в +// функцию (каррировать). + +var product = function(a, b){ return a * b; } +var doubler = product.bind(this, 2); +doubler(8); // = 16 + +// Когда функция вызывается с ключевым словом new, создается новый объект. +// Данный объект становится доступным функции через ключевое слово this. +// Функции спроектированные вызываться таким способом называются конструкторами. + +var MyConstructor = function(){ + this.myNumber = 5; +} +myNewObj = new MyConstructor(); // = {myNumber: 5} +myNewObj.myNumber; // = 5 + +// Любой объект в JavaScript имеет 'прототип'. Когда вы пытаетесь получить +// доступ к свойству не объявленному в данном объекте, интерпретатор будет +// искать его в прототипе. + +// Некоторые реализации JS позволяют получить доступ к прототипу с помощью +// "волшебного" свойства __proto__. До момента пока оно не являются стандартным, +// __proto__ полезно лишь для изучения прототипов в JavaScript. Мы разберемся +// со стандартными способами работы с прототипом несколько позже. +var myObj = { + myString: "Hello world!" +}; +var myPrototype = { + meaningOfLife: 42, + myFunc: function(){ + return this.myString.toLowerCase() + } +}; + +myObj.__proto__ = myPrototype; +myObj.meaningOfLife; // = 42 +myObj.myFunc(); // = "hello world!" + +// Естественно, если в свойства нет в прототипе, поиск будет продолжен в +// прототипе прототипа и так далее. +myPrototype.__proto__ = { + myBoolean: true +}; +myObj.myBoolean; // = true + +// Ничего не копируется, каждый объект хранит ссылку на свой прототип. Если +// изменить прототип, все изменения отразятся во всех его потомках. +myPrototype.meaningOfLife = 43; +myObj.meaningOfLife; // = 43 + +// Как было сказано выше, __proto__ не является стандартом, и нет стандартного +// способа изменить прототип у созданного объекта. Однако, есть два способа +// создать объект с заданным прототипом. + +// Первый способ - Object.create, был добавлен в JS относительно недавно, и +// потому не доступен в более ранних реализациях языка. +var myObj = Object.create(myPrototype); +myObj.meaningOfLife; // = 43 + +// Второй вариан доступен везде и связан с конструкторами. Конструкторы имеют +// свойство prototype. Это вовсе не прототип функции конструктора, напротив, +// это прототип, который присваевается новым объектам, созданным с этим +// конструктором с помощью ключевого слова new. +MyConstructor.prototype = { + myNumber: 5, + getMyNumber: function(){ + return this.myNumber; + } +}; +var myNewObj2 = new MyConstructor(); +myNewObj2.getMyNumber(); // = 5 +myNewObj2.myNumber = 6 +myNewObj2.getMyNumber(); // = 6 + +// У встроенных типов таких, как строки и числа, тоже есть конструкторы, +// создающие эквивалентные объекты-обертки. +var myNumber = 12; +var myNumberObj = new Number(12); +myNumber == myNumberObj; // = true + +// Правда, они не совсем эквивалентны. +typeof myNumber; // = 'number' +typeof myNumberObj; // = 'object' +myNumber === myNumberObj; // = false +if (0){ + // Этот фрагмент кода не будет выпонен, так как 0 приводится к false +} +if (Number(0)){ + // Этот фрагмент кода *будет* выпонен, так как Number(0) приводится к true. +} + +// Однако, оберточные объекты и обычные встроенные типы имеют общие прототипы, +// следовательно вы можете расширить функциональность строки, например. +String.prototype.firstCharacter = function(){ + return this.charAt(0); +} +"abc".firstCharacter(); // = "a" + +// Этот факт часто используется для создания полифилов(polyfill) - реализации +// новых возможностей JS в его более старых версиях для того чтобы их можно было +// использовать в устаревших браузерах. + +// Например, мы упомянули, что Object.create не доступен во всех версиях +// JavaScript, но мы можем создать полифилл. +if (Object.create === undefined){ // не переопределяем, если есть + Object.create = function(proto){ + // создаем временный конструктор с заданным прототипом + var Constructor = function(){}; + Constructor.prototype = proto; + // создаём новый объект с правильным прототипом + return new Constructor(); + } +} +``` + +## Что еще почитать + +[Современный учебник JavaScript](http://learn.javascript.ru/) от Ильи Кантора +является довольно качественным и глубоким учебным материалом, освещающим все +особенности современного языка. Помимо учебника на том же домене можно найти +[перевод спецификации ECMAScript 5.1](http://es5.javascript.ru/) и справочник по +возможностям языка. + +[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/ru/) позволяет +довольно быстро изучить основные тонкие места в работе с JS, но фокусируется +только на таких моментах + +[Справочник](https://developer.mozilla.org/ru/docs/JavaScript) от MDN +(Mozilla Development Network) содержит информацию о возможностях языка на +английском. + +Название проекта ["Принципы написания консистентного, идиоматического кода на +JavaScript"](https://github.com/rwaldron/idiomatic.js/tree/master/translations/ru_RU) +говорит само за себя. + |