diff options
Diffstat (limited to 'ru-ru')
| -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) +говорит само за себя. + | 
