1
0
mirror of https://github.com/adambard/learnxinyminutes-docs.git synced 2025-08-18 12:31:22 +02:00

translation javascript into Russian

This commit is contained in:
a.gonchar
2014-12-24 16:15:34 +03:00
committed by Adam
parent d2336d0ce4
commit 7b9eb42fb5

View File

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