From 980fe00a74a9ad013b945755415ace2e5429c3c2 Mon Sep 17 00:00:00 2001
From: Alexey Pyltsyn Числа в JavaScript — это "64-битные значения двойной точности формата IEEE 754", согласно спецификации. Это имеет интересные последствия. В JavaScript нет такой вещи, как целое число, поэтому с арифметикой нужно быть начеку, если вы привыкли к вычислениям в языках C или Java. Взгляните на пример: На практике целые значения это 32-битные целые (и хранятся таким образом в некоторых браузерных реализациях), что может быть важно для побитовых операций. Поддерживаются стандартные арифметические операторы, включая сложение, вычитание, остаток от деления и т.д. Есть ещё встроенный объект, который я забыл упомянуть, называемый Math, который содержит более продвинутые математические функции и константы: Вы можете преобразовать строку в целое число, используя встроенную функцию Если вы не предоставите основание, то можете получить неожиданные результаты: Если хотите преобразовать двоичное число в десятичное целое, просто смените основание: Вы можете аналогично парсить дробные числа, используя встроенную функцию Также можно использовать унарный оператор Специальное значение NaN (сокращение от "Not a Number") возвращается, если строка не является числом: Проверить значение на JavaScript также имеет специальные значения Проверить значение на Чтобы выяснить длину строки (в кодовых единицах), используйте свойство Это уже первый шаг для работы с объектами! Мы уже говорили, что и строки можно использовать как объекты? У них тоже есть методы: Преобразование значений можно осуществить явно, используя функцию Для объявления новых переменных в JavaScript используются ключевые слова Пример кода с переменной, объявленной с помощью JavaScript поддерживает такие операторы, как Оператор При сложении строкового и числового значений происходит автоматическое преобразование в строку. Поначалу такое может запутать: Для сравнения в JavaScript используются следующие операторы: Если преобразование нежелательно, то используют оператор строгого равенства: Управляющие структуры в JavaScript очень похожи на таковые в языках семейства C. Условные операторы выражены ключевыми словами В JavaScript есть три типа циклов: Цикл JavaScript также содержит две других известных конструкции: и Логические операторы Таким способом удобно задавать значения по умолчанию: К условным операторам в JavaScript принадлежит также тернарный оператор " Оператор Если в конце инструкции Вариант Существует два основных способа создать объект: А также: Обе эти записи делают одно и то же. Вторая запись называется литералом объекта и более удобная. Такой способ является основой формата JSON, и при написании кода лучше использовать именно его. С помощью литерала объекта можно создавать не только пустые объекты, но и объекты с данными: Доступ к свойствам объекта можно получить следующими способами: Эти два метода равнозначны. Первый метод используется, если мы точно знаем к какому методу нам нужно обратиться. Второй метод принимает в качестве имени свойства строку, и позволяет вычислять имя в процессе вычислений. Следует отметить, что последний метод мешает некоторым движкам и минимизаторам оптимизировать код. Если появится необходимость назначить в качестве имён свойств объекта зарезервированные слова, то данный метод тоже может пригодиться: Создать массив можно по старинке: Но гораздо удобнее использовать литерал массива: Запомните, свойство Если попытаться получить доступ к несуществующему элементу массива, то получите Для перебора элементов массива используйте такой способ: ES2015 представляет более краткий И самый новый способ перебора свойств массива был добавлен в ECMAScript 5 — это метод forEach(): Для добавления данных в массив используйте метод У массивов есть ещё множество полезных методов. С их полным списком вы можете ознакомиться по ссылке. Наряду с объектами функции также являются ключевыми компонентами языка JavaScript. Базовые функции очень просты: Можно вызвать функцию, вообще не передавая ей параметры. В таком случае будет считаться, что их значения равны Можно передать больше аргументов, чем ожидает функция: Это может показаться бессмысленным, но на самом деле функции могут получить доступ к "лишним" аргументам с помощью псевдомассива Или создадим функцию для вычисления среднего значения: Это довольно полезно, но при этом кажется излишне подробным. Для уменьшения количества кода взглянем на замену использования массива аргументов синтаксисом остаточных параметров. В этом случае мы можем передавать в функцию любое количество аргументов, сохраняя код минималистичным. Оператор остаточных параметров используется в списке параметров функции в формате: ...variable и включает в себя целый список аргументов, с которыми функция будет вызвана. Мы будем также использовать замену цикла for циклом for...of для получения значений, которые будет содержать наша переменная.0.1 + 0.2 == 0.30000000000000004
+
0.1 + 0.2 == 0.30000000000000004
Math.sin(3.5);
+
Math.sin(3.5);
var circumference = Math.PI * (r + r);
parseInt(). Её необязательный второй параметр — основание системы счисления, которое следует всегда явно указывать:parseInt("123", 10); // 123
+parseInt("123", 10); // 123
parseInt("010", 10); // 10
parseInt("010"); // 8
+parseInt("010"); // 8
parseInt("0x10"); // 16
@@ -84,41 +84,41 @@ parseInt("0x10"); // 16
parseInt("11", 2); // 3
+parseInt("11", 2); // 3
parseFloat(), которая использует всегда основание 10 в отличие от родственной parseInt().+ для преобразования значения в число:+ "42"; // 42
+
+ "42"; // 42
+ "0x10"; // 16
parseInt("hello", 10); // NaN
+parseInt("hello", 10); // NaN
NaN "заразителен": любая математическая операция над NaN возвращает NaN:NaN + 5; // NaN
+
NaN + 5; // NaN
NaN можно встроенной функцией isNaN():isNaN(NaN); // true
+
isNaN(NaN); // true
Infinity (бесконечность) и -Infinity:1 / 0; // Infinity
+
1 / 0; // Infinity
-1 / 0; // -Infinity
Infinity, -Infinity и NaN можно с помощью встроенной функции isFinite():isFinite(1/0); // false
+
isFinite(1/0); // false
isFinite(-Infinity); // false
isFinite(NaN); // false
@@ -133,12 +133,12 @@ isFinite(NaN); // false
length:"hello".length; // 5
+
"hello".length; // 5
"hello".charAt(0); // h
+
"hello".charAt(0); // h
"hello, world".replace("hello", "goodbye"); // goodbye, world
"hello".toUpperCase(); // HELLO
@@ -156,7 +156,7 @@ isFinite(NaN); // false
Boolean():Boolean(""); // false
+Boolean(""); // false
Boolean(234); // true
@@ -168,13 +168,13 @@ Boolean(234); // true
let, const или var.let a;
+
let a;
let name = "Simon";
let позволяет объявлять переменные, которые доступны только в блоке, в котором они объявлены:// myLetVariable недоступна здесь
+
// myLetVariable недоступна здесь
for (let myLetVariable = 0; myLetVariable < 5; myLetVariable++) {
// myLetVariable доступна только здесь
@@ -184,17 +184,17 @@ for (let myLetVariable = 0; myLetVariable < 5; myLetVariable++) {
const позволяет создавать переменные, чьи значения не предполагают изменений. Переменная доступна из блока, в котором она объявлена.const Pi = 3.14; // в переменную Pi записано значение.
+
const Pi = 3.14; // в переменную Pi записано значение.
Pi = 1; // вызовет исключение, так как значение константы нельзя изменить.
var наиболее общее средство объявления переменной. Оно не имеет ограничений, которые имеют два вышеописанных способа. Это потому, что это был изначально единственный способ объявления переменной в JavaScript. Переменная, объявленная с помощью var, доступна в пределах функции, в которой она объявлена.var a;
+
var a;
var name = 'Simon';
var:// myVarVariable доступна здесь
+
// myVarVariable доступна здесь
for (var myVarVariable = 0; myVarVariable < 5; myVarVariable++) {
// myVarVariable доступна для всей функции
@@ -210,7 +210,7 @@ for (var myVarVariable = 0; myVarVariable < 5; myVarVariable++) {
+, -, *, / и %, который возвращает остаток от деления (не путать с модулем). Значения присваиваются с помощью оператора =, или с помощью составных операторов += и -=. Это сокращённая запись выражения x = x оператор y.x += 5
+
x += 5
x = x + 5
@@ -218,12 +218,12 @@ x = x + 5
+ так же выполняет конкатенацию (объединение) строк:"hello" + " world"; // "hello world"
+
"hello" + " world"; // "hello world"
"3" + 4 + 5; // "345"
+
"3" + 4 + 5; // "345"
3 + 4 + "5"; // "75"
@@ -231,12 +231,12 @@ x = x + 5
<, >, <= и >=. Сравнивать можно не только числа, но и строки. Проверка на равенство немного сложнее. Для проверки используют двойной (==) или тройной (===) оператор присваивания. Двойной оператор == осуществляет автоматическое преобразование типов, что может приводить к интересным результатам:123 == "123"; // true
+
123 == "123"; // true
1 == true; // true
1 === true; // false
+
1 === true; // false
123 === "123"; // false
true === true; // true
@@ -248,7 +248,7 @@ true === true; // trueif и else, которые можно составлять в цепочки:var name = "kittens";
+
var name = "kittens";
if (name == "puppies") {
name += "!";
} else if (name == "kittens") {
@@ -261,7 +261,7 @@ name == "kittens!!"
while, do-while и for. While используется для задания обычного цикла, а do-while целесообразно применить в том случае, если вы хотите, чтобы цикл был выполнен хотя бы один раз:while (true) {
+while (true) {
// бесконечный цикл!
}
@@ -273,41 +273,41 @@ do {
for похож на такой же в языках C и Java: он позволяет задавать данные для контроля за выполнением цикла:for (var i = 0; i < 5; i++) {
+for (var i = 0; i < 5; i++) {
// Выполнится 5 раз
}
for...offor (let value of array) {
+for (let value of array) {
// операции с value
}
for...in:for (let property in object) {
+for (let property in object) {
// операции над свойствами объекта
}
&& и || используют "короткий цикл вычисления", это значит, что вычисление каждого последующего оператора зависит от предыдущего. Например, полезно проверить существует ли объект или нет, прежде чем пытаться получить доступ к его свойствам:var name = o && o.getName();
+
var name = o && o.getName();
var name = otherName || "default";
+
var name = otherName || "default";
?" :var allowed = (age > 18) ? "yes" : "no";
+
var allowed = (age > 18) ? "yes" : "no";
switch используется при необходимости множественного сравнения:switch(action) {
+switch(action) {
case 'draw':
drawit();
break;
@@ -321,7 +321,7 @@ do {
case не добавить останавливающую инструкцию break, то выполнение перейдёт к следующей инструкции case. Как правило, такое поведение нежелательно, но если вдруг вы решили его использовать, настоятельно рекомендуем писать соответствующий комментарий для облегчения поиска ошибок:switch(a) {
+switch(a) {
case 1: // fallthrough
case 2:
eatit();
@@ -333,7 +333,7 @@ do {
default опциональный. Допускается использование выражений как в условии switch, так и в cases. При проверке на равенство используется оператор строгого равенства ===:switch(1 + 3) {
+switch(1 + 3) {
case 2 + 2:
yay();
break;
@@ -358,19 +358,19 @@ do {
var obj = new Object();
+
var obj = new Object();
var obj = {};
+var obj = {};
var obj = {
+var obj = {
name: "Carrot",
"for": "Max",
details: {
@@ -382,12 +382,12 @@ do {
obj.details.color; // orange
+
obj.details.color; // orange
obj['details']['size']; // 12
// Вызовет Syntax error, ведь 'for' это зарезервированное слово
+
// Вызовет Syntax error, ведь 'for' это зарезервированное слово
obj.for = "Simon";
// А тут всё нормально
@@ -413,7 +413,7 @@ obj["for"] = "Simon";
var a = new Array();
+
var a = new Array();
a[0] = "dog";
a[1] = "cat";
a[2] = "hen";
@@ -422,13 +422,13 @@ a.length; // 3
var a = ["dog", "cat", "hen"];
+
var a = ["dog", "cat", "hen"];
a.length; // 3
array.length не обязательно будет показывать количество элементов в массиве. Посмотрите пример:var a = ["dog", "cat", "hen"];
+
var a = ["dog", "cat", "hen"];
a[100] = "fox";
a.length; // 101
@@ -437,19 +437,19 @@ a.length; // 101
undefined:typeof a[90]; // undefined
+
typeof a[90]; // undefined
for (var i = 0; i < a.length; i++) {
+for (var i = 0; i < a.length; i++) {
// Сделать что-нибудь с элементом a[i]
}
for...of способ обхода по итерируемым объектам, в т.ч. массивам:for (const currentValue of a) {
+
@@ -458,13 +458,13 @@ a.length; // 101
for (const currentValue of a) {
// Сделать что-нибудь с currentValue
}
["dog", "cat", "hen"].forEach(function(currentValue, index, array) {
+["dog", "cat", "hen"].forEach(function(currentValue, index, array) {
// Сделать что-нибудь с currentValue или array[index]
});
push():a.push(item);
+a.push(item);
function add(x, y) {
+function add(x, y) {
var total = x + y;
return total;
}
@@ -541,17 +541,17 @@ a.length; // 101
undefined:add(); // NaN
+
add(); // NaN
// Нельзя проводить сложение undefined и undefined
add(2, 3, 4); // 5
+
add(2, 3, 4); // 5
// используются только первые два аргумента, "4" игнорируется
arguments, в нём содержатся значения всех аргументов, переданных функции. Давайте напишем функцию, которая принимает неограниченное количество аргументов:function add() {
+function add() {
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += arguments[i];
@@ -564,7 +564,7 @@ add(2, 3, 4, 5); // 14
function avg() {
+function avg() {
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += arguments[i];
@@ -576,7 +576,7 @@ avg(2, 3, 4, 5); // 3.5
function avg(...args) {
+function avg(...args) {
var sum = 0;
for (let value of args) {
sum += value;
@@ -592,7 +592,7 @@ avg(2, 3, 4, 5); // 3.5
Важно отметить, что где бы ни был размещён rest parameter operator в объявлении функции, он будет содержать все аргументы после его объявления, не раньше. например: function avg(firstValue, ...args) будет хранить первое переданное значение в переменной firstValue и оставшиеся в args. Это ещё одно полезное свойство языка, однако оно ведёт нас к новой проблеме. avg() функция принимает список аргументов, разделённый запятыми. Но что если вы хотите найти среднее значение в массиве? Вы можете переписать функцию следующим образом:
function avgArray(arr) {
+function avgArray(arr) {
var sum = 0;
for (var i = 0, j = arr.length; i < j; i++) {
sum += arr[i];
@@ -604,7 +604,7 @@ avgArray([2, 3, 4, 5]); // 3.5
На тот случай, если вы хотите использовать первый вариант функции, а не переписывать её заново, то в JavaScript есть возможность вызывать функцию с произвольным массивом аргументов. Для этого используется метод apply():
-avg.apply(null, [2, 3, 4, 5]); // 3.5
+avg.apply(null, [2, 3, 4, 5]); // 3.5
Вторым аргументом метода apply() передаётся массив, который будет передан функции в качестве аргументов. О первом аргументе мы поговорим позже. Наличие у функций методов также говорит о том, что на самом деле они являются объектами.
@@ -617,7 +617,7 @@ avgArray([2, 3, 4, 5]); // 3.5
В JavaScript можно создавать анонимные функции:
-var avg = function() {
+var avg = function() {
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += arguments[i];
@@ -628,7 +628,7 @@ avgArray([2, 3, 4, 5]); // 3.5
Данная запись семантически равнозначна записи function avg(). Это даёт возможность использовать разные интересные трюки. Вот посмотрите, как можно "спрятать" локальные переменные в функции:
-var a = 1;
+var a = 1;
var b = 2;
(function() {
var b = 3;
@@ -640,7 +640,7 @@ b; // 2
В JavaScript есть возможность рекурсивного вызова функции. Это может оказаться полезным при работе с иерархическими (древовидными) структурами данных (например такие, которые встречаются при работе с DOM).
-function countChars(elm) {
+function countChars(elm) {
if (elm.nodeType == 3) { // TEXT_NODE
return elm.nodeValue.length;
}
@@ -654,7 +654,7 @@ b; // 2
Тут мы сталкиваемся с проблемой: как вызвать функцию рекурсивно, если у неё нет имени? Для этого в JavaScript есть именованные функциональные выражения IIFEs (Immediately Invoked Function Expressions). Вот пример использования именованной самовызывающейся функции:
-var charsInBody = (function counter(elm) {
+var charsInBody = (function counter(elm) {
if (elm.nodeType == 3) { // TEXT_NODE
return elm.nodeValue.length;
}
@@ -675,7 +675,7 @@ b; // 2
В классическом Объектно-Ориентированном Программировании (ООП) объекты — это коллекции данных и методов, которые этими данными оперируют. JavaScript - это язык, основанный на прототипах, и в его определении нет понятия классов, таких, как в языках C++ или Java. (Иногда это может запутать программистов, знакомых с языками, в которых есть классы.) Вместо классов JavaScript использует функции. Давайте представим объект с личными данными, содержащий поля с именем и фамилией. Есть два типа отображения имён: "Имя Фамилия" или "Фамилия, Имя". С помощью объектов и функций можно сделать следующее:
-function makePerson(first, last) {
+function makePerson(first, last) {
return {
first: first,
last: last
@@ -698,7 +698,7 @@ personFullNameReversed(s); // Willison, Simon
Работает, но сам код никуда не годится. С таким подходом у вас будут десятки функций, засоряющих глобальный объект. Это можно исправить, прикрепив функцию к объекту. Это просто, ведь все функции и есть объекты:
-function makePerson(first, last) {
+function makePerson(first, last) {
return {
first: first,
last: last,
@@ -717,7 +717,7 @@ s.fullNameReversed(); // Willison, Simon
А вот кое-что новенькое: ключевое слово 'this'. Когда 'this' используется внутри функции, оно ссылается на текущий объект. Значение ключевого слова зависит от способа вызова функции. Если вызвать функцию с обращением к объекту через точку или квадратные скобки, то 'this' получится равным данному объекту. В ином случае 'this' будет ссылаться на глобальный объект. Это часто приводит к ошибкам. Например:
-s = makePerson("Simon", "Willison")
+s = makePerson("Simon", "Willison")
var fullName = s.fullName;
fullName(); // undefined undefined
@@ -726,7 +726,7 @@ fullName(); // undefined undefined
Используя особенность ключевого слова 'this', можно улучшить код функции makePerson:
-function Person(first, last) {
+function Person(first, last) {
this.first = first;
this.last = last;
this.fullName = function() {
@@ -745,7 +745,7 @@ var s = new Person("Simon", "Willison");
Каждый раз, когда с помощью конструктора создаётся новый объект, мы заново создаём и две новые функции. Гораздо удобнее создать эти функции отдельно и дать доступ к ним конструктору:
-function personFullName() {
+function personFullName() {
return this.first + ' ' + this.last;
}
function personFullNameReversed() {
@@ -761,7 +761,7 @@ function Person(first, last) {
Уже лучше: мы создали функции-методы только один раз, а при новом вызове функции-конструктора просто ссылаемся на них. Можно сделать ещё лучше? Конечно:
-function Person(first, last) {
+function Person(first, last) {
this.first = first;
this.last = last;
}
@@ -777,7 +777,7 @@ function Person(first, last) {
Это очень мощный инструмент. JavaScript позволяет изменять прототипы в любое время, это значит, что можно добавлять новые методы к существующим объектам во время выполнения программы:
-s = new Person("Simon", "Willison");
+s = new Person("Simon", "Willison");
s.firstNameCaps();
// TypeError on line 1: s.firstNameCaps is not a function
@@ -789,7 +789,7 @@ s.firstNameCaps(); // "SIMON"
Занимательно то, что добавлять свойства в прототип можно и для встроенных объектов JavaScript. Давайте добавим новый метод reversed классу String, этот метод будет возвращать строку задом наперёд:
-var s = "Simon";
+var s = "Simon";
s.reversed(); // TypeError on line 1: s.reversed is not a function
String.prototype.reversed = function reversed() {
@@ -804,13 +804,13 @@ s.reversed(); // "nomiS"
Данный метод будет работать даже на литералах строки!
-"This can now be reversed".reversed();
+"This can now be reversed".reversed();
// desrever eb won nac sihT
Как уже упоминалось, prototype формирует часть цепочки. Конечным объектом этой цепочки прототипов является Object.prototype, методы которого включают и toString() — тот метод, который вызывается тогда, когда надо получить строковое отображение объекта. Вот что можно сделать с нашими объектами Person:
-var s = new Person("Simon", "Willison");
+var s = new Person("Simon", "Willison");
s.toString(); // [object Object]
Person.prototype.toString = function() {
@@ -821,7 +821,7 @@ s.toString(); // "<Person: Simon Willison>"
Помните, мы вызывали avg.apply() с первым аргументом равным null? Теперь мы можем сделать так: первым аргументом, переданным методу apply() будет объект, который примет значение 'this'. Вот к примеру упрощённая реализация 'new':
-function trivialNew(constructor, ...args) {
+function trivialNew(constructor, ...args) {
var o = {}; // Создаём новый объект
constructor.apply(o, args);
return o;
@@ -832,15 +832,15 @@ s.toString(); // "<Person: Simon Willison>"
Вызов
-var bill = trivialNew(Person, 'William', 'Orange');
+var bill = trivialNew(Person, 'William', 'Orange');
практически полностью эквивалентен этому:
-var bill = new Person('William', 'Orange');
+var bill = new Person('William', 'Orange');
В JavaScript метод apply() имеет похожий метод call(), который тоже позволяет устанавливать 'this', но принимает список, а не массив аргументов.
-function lastNameCaps() {
+function lastNameCaps() {
return this.last.toUpperCase();
}
var s = new Person("Simon", "Willison");
@@ -853,7 +853,7 @@ s.lastNameCaps(); // WILLISON
Объявлять новые функции можно и внутри других функций. Мы использовали этот приём чуть выше, создавая функцию makePerson(). Главная особенность вложенных функций в том, что они получают доступ к переменным, объявленным в их функции-родителе:
-function parentFunc() {
+function parentFunc() {
var a = 1;
function nestedFunc() {
@@ -871,7 +871,7 @@ s.lastNameCaps(); // WILLISON
Мы подошли к одному из самых мощных и непонятных инструментов JavaScript. Давайте разберёмся.
-function makeAdder(a) {
+function makeAdder(a) {
return function(b) {
return a + b;
};
@@ -887,7 +887,7 @@ y(7); // ?
Такой же фокус мы наблюдали в предыдущем примере, когда внутренние функции получали доступ к переменным той функции, в которой были объявлены. Только в нашем примере основная функция возвращает вложенную. Поначалу может показаться, что локальные переменные при этом перестанут существовать. Но они продолжают существовать — иначе код попросту не сработал бы. Вдобавок ко всему у нас есть две разные "копии" функции makeAdder, присвоенные разным переменным (одна копия, в которой а - это 5, а во второй а - это 20). Вот что имеем в результате вызова:
-x(6); // возвратит 11
+x(6); // возвратит 11
y(7); // возвратит 27
diff --git a/files/ru/web/javascript/closures/index.html b/files/ru/web/javascript/closures/index.html
index 5d8d80d292..c9d5c026fe 100644
--- a/files/ru/web/javascript/closures/index.html
+++ b/files/ru/web/javascript/closures/index.html
@@ -15,7 +15,7 @@ translation_of: Web/JavaScript/Closures
Рассмотрим следующий пример:
-function init() {
+function init() {
var name = "Mozilla"; // name - локальная переменная, созданная в init
function displayName() { // displayName() - внутренняя функция, замыкание
alert (name); // displayName() использует переменную, объявленную в родительской функции
@@ -35,7 +35,7 @@ init();
Рассмотрим следующий пример:
-function makeFunc() {
+function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
@@ -55,7 +55,7 @@ myFunc();
А вот немного более интересный пример — функция makeAdder:
-function makeAdder(x) {
+function makeAdder(x) {
return function(y) {
return x + y;
};
@@ -84,7 +84,7 @@ console.log(add10(2)); // 12
Давайте рассмотрим практический пример: допустим, мы хотим добавить на страницу несколько кнопок, которые будут менять размер текста. Как вариант, мы можем указать свойство font-size на элементе body в пикселах, а затем устанавливать размер прочих элементов страницы (таких, как заголовки) с использованием относительных единиц em:
-body {
+body {
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
}
@@ -102,7 +102,7 @@ h2 {
Используем следующий JavaScript:
-function makeSizer(size) {
+function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
@@ -115,12 +115,12 @@ var size16 = makeSizer(16);
Теперь size12, size14, и size16 - это функции, которые меняют размер текста в элементе body на значения 12, 14, и 16 пикселов, соответственно. После чего мы цепляем эти функции на кнопки примерно так:
-document.getElementById('size-12').onclick = size12;
+document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
-<a href="#" id="size-12">12</a>
+<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>
@@ -135,7 +135,7 @@ document.getElementById('size-16').onclick = size16;
Код ниже иллюстрирует, как можно использовать замыкания для определения публичных функций, которые имеют доступ к закрытым от пользователя (private) функциям и переменным. Такая манера программирования называется модульное программирование:
-var Counter = (function() {
+var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
@@ -169,7 +169,7 @@ alert(Counter.value()); /* Alerts 1 */
Заметьте, мы описываем анонимную функцию, создающую счётчик, и тут же запускаем её, присваивая результат исполнения переменной Counter. Но мы также можем не запускать эту функцию сразу, а сохранить её в отдельной переменной, чтобы использовать для дальнейшего создания нескольких счётчиков вот так:
-var makeCounter = function() {
+var makeCounter = function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
@@ -206,13 +206,13 @@ alert(Counter2.value()); /* Alerts 0 */
До того, как в версии ECMAScript 6 ввели ключевое слово let, постоянно возникала следующая проблема при создании замыканий внутри цикла. Рассмотрим пример:
-<p id="help">Helpful notes will appear here</p>
+<p id="help">Helpful notes will appear here</p>
<p>E-mail: <input type="text" id="email" name="email"></p>
<p>Name: <input type="text" id="name" name="name"></p>
<p>Age: <input type="text" id="age" name="age"></p>
-function showHelp(help) {
+function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
@@ -244,7 +244,7 @@ setupHelp();
В качестве решения в этом случае можно предложить использование функции, фабричной функции (function factory), как уже было описано выше в примерах:
-function showHelp(help) {
+function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
@@ -282,7 +282,7 @@ setupHelp();
Давайте рассмотрим не очень практичный, но показательный пример:
-function MyObject(name, message) {
+function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
this.getName = function() {
@@ -297,7 +297,7 @@ setupHelp();
Поскольку вышеприведённый код никак не использует преимущества замыканий, его можно переписать следующим образом:
-function MyObject(name, message) {
+function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
@@ -313,7 +313,7 @@ MyObject.prototype = {
Методы вынесены в прототип. Тем не менее, переопределять прототип — само по себе является плохой привычкой, поэтому давайте перепишем всё так, чтобы новые методы просто добавились к уже существующему прототипу.
-function MyObject(name, message) {
+function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
@@ -327,7 +327,7 @@ MyObject.prototype.getMessage = function() {
Код выше можно сделать аккуратнее:
-function MyObject(name, message) {
+function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
diff --git a/files/ru/web/javascript/data_structures/index.html b/files/ru/web/javascript/data_structures/index.html
index 71eeb219ef..fee4fc9283 100644
--- a/files/ru/web/javascript/data_structures/index.html
+++ b/files/ru/web/javascript/data_structures/index.html
@@ -15,7 +15,7 @@ translation_of: Web/JavaScript/Data_structures
JavaScript является слабо типизированным или динамическим языком. Это значит, что вам не нужно определять тип переменной заранее. Тип определится автоматически во время выполнения программы. Также это значит, что вы можете использовать одну переменную для хранения данных различных типов:
-var foo = 42; // сейчас foo типа Number
+var foo = 42; // сейчас foo типа Number
foo = "bar"; // а теперь foo типа String
foo = true; // foo становится типа Boolean
@@ -66,7 +66,7 @@ foo = true; // foo становится типа Boolean
Ноль в JavaScript имеет два представления: -0 и +0. («0» это синоним +0). На практике это имеет малозаметный эффект. Например, выражение +0 === -0 является истинным. Однако, это может проявиться при делении на ноль:
-> 42 / +0
+> 42 / +0
Infinity
> 42 / -0
-Infinity
@@ -106,7 +106,7 @@ Infinity
BigInt является встроенным объектом, который предоставляет способ представления целых чисел, которые больше 2 53, что является наибольшим числом, которое JavaScript может надёжно представить с помощью Number примитива.
-> let bigInt = 19241924124n;
+> let bigInt = 19241924124n;
> console.log(bigInt);
19241924124n
> console.log(typeof bigInt);
diff --git a/files/ru/web/javascript/guide/control_flow_and_error_handling/index.html b/files/ru/web/javascript/guide/control_flow_and_error_handling/index.html
index 005a702243..4101047db0 100644
--- a/files/ru/web/javascript/guide/control_flow_and_error_handling/index.html
+++ b/files/ru/web/javascript/guide/control_flow_and_error_handling/index.html
@@ -24,13 +24,13 @@ translation_of: Web/JavaScript/Guide/Control_flow_and_error_handling
Блок обычно используется с управляющими инструкциями (например, if, for, while).
-while (x < 10) { x++; }
+while (x < 10) { x++; }
В вышеприведённом примере { x++; } является блоком.
Обратите внимание: в JavaScript отсутствует область видимости блока до ECMAScript2015. Переменные, объявленные внутри блока, имеют область видимости функции (или скрипта), в которой находится данный блок, вследствие чего они сохранят свои значения при выходе за пределы блока. Другими словами, блок не создаёт новую область видимости. "Автономные" (standalone) блоки в JavaScript могут продуцировать полностью отличающийся результат, от результата в языках C или Java. Например:
-var x = 1;
+var x = 1;
{
var x = 2;
}
@@ -48,7 +48,7 @@ console.Используйте оператор if для выполнения инструкции, если логическое условия истинно. Используйте опциональный else, для выполнения инструкции, если условие ложно. Оператор if выглядит так:
-if (condition) {
+if (condition) {
statement_1;
} else {
statement_2;
@@ -58,7 +58,7 @@ console.Также вы можете объединить несколько инструкций, пользуясь else if для получения последовательности проверок условий:
-if (condition_1) { statement_1;} else if (condition_2) { statement_2;} else if (condition_n) { statement_n; } else { statement_last;}
+if (condition_1) { statement_1;} else if (condition_2) { statement_2;} else if (condition_n) { statement_n; } else { statement_last;}
В случае нескольких условий только первое логическое условие, которое вычислится истинным (true), будет выполнено. Используйте блок ( { ... } ) для группировки нескольких инструкций. Применение блоков является хорошей практикой, особенно когда используются вложенные инструкции if:
@@ -72,12 +72,12 @@ console.Нежелательно использовать простые присваивания в условном выражении, т.к. присваивание может быть спутано с равенством при быстром просмотре кода. Например, не используйте следующий код:
-if (x = y) { /* ... */ }
+if (x = y) { /* ... */ }
Если вам нужно использовать присваивание в условном выражении, то распространённой практикой является заключение операции присваивания в дополнительные скобки. Например:
-if ( (x = y) ) { /* ... */ }
+if ( (x = y) ) { /* ... */ }
Ложные значения
@@ -96,14 +96,14 @@ console.Не путайте примитивные логические значения true и false со значениями true и false объекта {{jsxref("Boolean")}}. Например:
-var b = new Boolean(false);
+var b = new Boolean(false);
if (b) // это условие true
if (b == true) // это условие false
В следующем примере функция checkData возвращает true, если число символов в объекте Text равно трём; в противном случае функция отображает окно alert и возвращает false.
-function checkData() {
+function checkData() {
if (document.form1.threeChar.value.length == 3) {
return true;
} else {
@@ -117,7 +117,7 @@ if (b == true) // это условие false
Инструкция switch позволяет сравнить значение выражения с различными вариантами и при совпадении выполнить соответствующий код. Инструкция имеет следующий вид:
-switch (expression) {
+switch (expression) {
case label_1:
statements_1
[break;]
@@ -137,7 +137,7 @@ if (b == true) // это условие false
В следующем примере если fruittype имеет значение "Bananas", то будет выведено сообщение "Bananas are $0.48 a pound." и оператор break прекратит выполнение switch. Если бы оператор break отсутствовал, то был бы также выполнен код, соответствующий ветви "Cherries", т.е. выведено сообщение "Cherries are $3.00 a pound.".
-switch (fruittype) {
+switch (fruittype) {
case "Oranges":
console.log("Oranges are $0.59 a pound.");
break;
@@ -182,7 +182,7 @@ console.Вы можете выбросить любое выражение, а не только выражения определённого типа. В следующем примере выбрасываются исключения различных типов:
-throw "Error2"; // string
+throw "Error2"; // string
throw 42; // number
throw true; // boolean
throw { toString: function() { return "I'm an object!"; } }; // object
@@ -191,7 +191,7 @@ console.В следующем примере объект UserException выбрасывается как исключение:
-function UserException (message) {
+function UserException (message) {
this.message = message;
this.name = "UserException";
}
@@ -208,7 +208,7 @@ console.В следующем примере вызывается функция getMonthName, которая возвращает название месяца по его номеру. Если месяца с указанным номером не существует, то функция выбросит исключение "InvalidMonthNo", которое будет перехвачено в блоке catch:
-function getMonthName(mo) {
+function getMonthName(mo) {
mo = mo - 1; // Adjust month number for array index (1 = Jan, 12 = Dec)
var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul",
"Aug","Sep","Oct","Nov","Dec"];
@@ -239,7 +239,7 @@ catch (e) {
В следующем примере выбрасывается исключение, которое перехватывается в блоке catch:
-try {
+try {
throw "myException"
} catch (e) {
console.error(e);
@@ -251,7 +251,7 @@ catch (e) {
В следующем примере открывается файл, затем в блоке try происходит вызов функции writeMyFile, который может выбросить исключение. Если возникает исключение, то оно обрабатывается в блоке catch. В любом случае файл будет закрыт функцией closeMyFile, вызов которой находится в блоке finally.
-openMyFile();
+openMyFile();
try {
writeMyFile(theData);
} catch(e) {
@@ -262,7 +262,7 @@ catch (e) {
Если блок finally возвращает значение, то данное значение становится возвращаемым значением всей связки try-catch-finally. Значения, возвращаемые блоками try и catch, будут проигнорированы.
-function f() {
+function f() {
try {
console.log(0);
throw "bogus";
@@ -282,7 +282,7 @@ catch (e) {
Замена возвращаемых значений блоком finally распространяется в том числе и на исключения, которые выбрасываются или перевыбрасываются в блоке catch:
-function f() {
+function f() {
try {
throw "bogus";
} catch(e) {
@@ -314,7 +314,7 @@ catch (e) {
Если вы выбрасываете собственные исключения, то чтобы получить преимущество, которое предоставляют эти свойства (например, если ваш блок catch не делает различий между вашими исключениями и системными), используйте конструктор Error. Например:
-function doSomethingErrorProne () {
+function doSomethingErrorProne () {
if ( ourCodeMakesAMistake() ) {
throw ( new Error('The message') );
} else {
@@ -348,7 +348,7 @@ catch (e) {
Простой пример использования объектов Promise и XMLHttpRequest для загрузки изображения доступен в репозитории MDN promise-test на GitHub. Вы также можете посмотреть его в действии. Каждый шаг прокомментирован, что позволяет вам разобраться в архитектуре Promise и XHR. Здесь приводится версия без комментариев:
-function imgLoad(url) {
+function imgLoad(url) {
return new Promise(function(resolve, reject) {
var request = new XMLHttpRequest();
request.open('GET', url);
diff --git a/files/ru/web/javascript/guide/modules/index.html b/files/ru/web/javascript/guide/modules/index.html
index 8bf2b4af9c..8416503814 100644
--- a/files/ru/web/javascript/guide/modules/index.html
+++ b/files/ru/web/javascript/guide/modules/index.html
@@ -43,7 +43,7 @@ translation_of: Web/JavaScript/Guide/Modules
В первом примере (см. директорию basic-modules) у нас следующая структура файлов:
-index.html
+index.html
main.js
modules/
canvas.js
@@ -106,7 +106,7 @@ modules/
Самый простой способ использовать экспорт — поместить конструкцию export перед любыми элементами, которые вы хотите экспортировать из модуля, например:
-export const name = 'square';
+export const name = 'square';
export function draw(ctx, length, x, y, color) {
ctx.fillStyle = color;
@@ -125,13 +125,13 @@ export function draw(ctx, length, x, y, color) {
Более удобный способ экспорта всех элементов, которые вы хотите экспортировать,— использовать одну конструкцию export в конце файла модуля, где указать переменные, функции, классы, который вы хотите экспортировать, через запятую в фигурных скобках. Например:
-export { name, draw, reportArea, reportPerimeter };
+export { name, draw, reportArea, reportPerimeter };
Импорт функционала в ваш скрипт
После того, как вы экспортировали некоторые функции из своего модуля, вам необходимо импортировать их в свой скрипт, чтобы иметь возможность использовать их. Самый простой способ сделать это:
-import { name, draw, reportArea, reportPerimeter } from './modules/square.js';
+import { name, draw, reportArea, reportPerimeter } from './modules/square.js';
Используйте конструкцию {{JSxRef("Statements/import", "import")}}, за которой следует разделенный запятыми список функций, которые вы хотите импортировать, заключённый в фигурные скобки, за которым следует ключевое слово from, за которым следует путь к файлу модуля — путь относительно корня сайта, который для нашего примера basic-modules будет равен /js-examples/modules/basic-modules.
@@ -140,11 +140,11 @@ export function draw(ctx, length, x, y, color) {
Так например:
-/js-examples/modules/basic-modules/modules/square.js
+/js-examples/modules/basic-modules/modules/square.js
становится
-./modules/square.js
+./modules/square.js
Вы можете найти подобные строки кода в файле main.js.
@@ -155,7 +155,7 @@ export function draw(ctx, length, x, y, color) {
После того, как вы импортировали функции в свой скрипт, вы можете использовать их так же, как если бы они были определены в этом же файле.
Следующий пример можно найти в main.js, сразу за строками импорта:
-let myCanvas = create('myCanvas', document.body, 480, 320);
+let myCanvas = create('myCanvas', document.body, 480, 320);
let reportList = createReportList(myCanvas.id);
let square1 = draw(myCanvas.ctx, 50, 50, 100, 'blue');
@@ -177,11 +177,11 @@ reportPerimeter(square1.length, reportList);
Прежде всего, вам нужно добавить type="module" в <script>-элемент, чтобы объявить, что скрипт является модулем. Чтобы подключить модуль main.js, нужно написать следующее:
-<script type="module" src="main.js"></script>
+<script type="module" src="main.js"></script>
Вы также можете встроить скрипт модуля непосредственно в HTML-файл, поместив JavaScript-код внутрь <script>-элемента:
-<script type="module">
+<script type="module">
/* код JavaScript модуля */
</script>
@@ -213,25 +213,25 @@ reportPerimeter(square1.length, reportList);
Давайте посмотрим на пример, и мы объясним, как это работает.
В модуле square.js из нашего примера вы можете найти функцию randomSquare(), которая создаёт квардрат случайного цвета и размера со случайными координатами. Мы хотим экпортировать эту функции по умолчанию, поэтому в конце файла пишем следующее:
-export default randomSquare;
+export default randomSquare;
Обратите внимание на отсутствие фигурных скобок.
Кстати, можно было бы определить функцию как анонимную и добавить к ней export default:
-export default function(ctx) {
+export default function(ctx) {
...
}
В нашем файле main.js мы импортируем функцию по умолчанию, используя эту строку:
-import randomSquare from './modules/square.js';
+import randomSquare from './modules/square.js';
Снова обратите внимание на отсутствие фигурных скобок.
Такой синтакис допустим, поскольку для каждого модуля разрешен только один экспорт по умолчанию, и мы знаем, что это randomSquare.
Вышеупомянутая строка является сокращением для:
-import {default as randomSquare} from './modules/square.js';
+import {default as randomSquare} from './modules/square.js';
Примечание: «as» синтаксис для переименования экспортируемых элементов поясняется ниже в разделе Переименование импорта и экмпорта.
@@ -252,7 +252,7 @@ reportPerimeter(square1.length, reportList);
Так, например, оба следующих элемента будут выполнять одну и ту же работу, хотя и немного по-разному:
-// внутри module.js
+// внутри module.js
export {
function1 as newFunctionName,
function2 as anotherNewFunctionName
@@ -261,7 +261,7 @@ export {
// внутри main.js
import { newFunctionName, anotherNewFunctionName } from './modules/module.js';
-// внутри module.js
+// внутри module.js
export { function1, function2 };
// внутри main.js
@@ -274,11 +274,11 @@ import { function1 as newFunctionName,
Внутри каждого из этих модулей у нас есть функции с одинаковыми именами, которые экспортируются, и поэтому у каждого из них есть один и тот же оператор export внизу файла:
-export { name, draw, reportArea, reportPerimeter };
+export { name, draw, reportArea, reportPerimeter };
Если бы в main.js при их импорте мы попытались использовать
-import { name, draw, reportArea, reportPerimeter } from './modules/square.js';
+import { name, draw, reportArea, reportPerimeter } from './modules/square.js';
import { name, draw, reportArea, reportPerimeter } from './modules/circle.js';
import { name, draw, reportArea, reportPerimeter } from './modules/triangle.js';
@@ -286,7 +286,7 @@ import { name, draw, reportArea, reportPerimeter } from './modules/triangle.js';
Вместо этого нам нужно переименовать импорт, чтобы он был уникальным:
-import { name as squareName,
+import { name as squareName,
draw as drawSquare,
reportArea as reportSquareArea,
reportPerimeter as reportSquarePerimeter } from './modules/square.js';
@@ -303,13 +303,13 @@ import { name as triangleName,
Обратите внимание, что вместо этого вы можете решить проблему в файлах модуля, например.
-// внутри square.js
+// внутри square.js
export { name as squareName,
draw as drawSquare,
reportArea as reportSquareArea,
reportPerimeter as reportSquarePerimeter };
-// внутри main.js
+// внутри main.js
import { squareName, drawSquare, reportSquareArea, reportSquarePerimeter } from './modules/square.js';
И это сработало бы точно так же.
@@ -322,11 +322,11 @@ import { squareName, drawSquare, reportSquareArea, reportSquarePerimeter } from
Существует решение получше — импортировать функции каждого модуля внутри объекта модуля.
Для этого используется следующая синтаксическая форма:
-import * as Module from './modules/module.js';
+import * as Module from './modules/module.js';
Эта конструкция берёт все экспорты, доступные внутри module.js и делает их доступными в качестве свойств объекта Module, фактически давая ему собственное пространство имен. Так например:
-Module.function1()
+Module.function1()
Module.function2()
и т.д.
@@ -335,11 +335,11 @@ Module.function2()
вы снова увидите тот же самый пример, но переписанный с учётом преимуществ этого нового синтаксиса.
В модулях все экспорты представлены в следующей простой форме:
-export { name, draw, reportArea, reportPerimeter };
+export { name, draw, reportArea, reportPerimeter };
С другой стороны, импорт выглядит так:
-import * as Canvas from './modules/canvas.js';
+import * as Canvas from './modules/canvas.js';
import * as Square from './modules/square.js';
import * as Circle from './modules/circle.js';
@@ -347,7 +347,7 @@ import * as Triangle from './modules/triangle.js';
В каждом случае теперь вы можете получить доступ к импорту модуля под указанным свойством объекта, например:
-let square1 = Square.draw(myCanvas.ctx, 50, 50, 100, 'blue');
+let square1 = Square.draw(myCanvas.ctx, 50, 50, 100, 'blue');
Square.reportArea(square1.length, reportList);
Square.reportPerimeter(square1.length, reportList);
@@ -360,7 +360,7 @@ Square.reportPerimeter(square1.length, reportList);
Вы можете увидеть пример нашего модуля для рисования фигур, переписанного с помощью классов ES в нашей classes директории.
В качестве примера, файд square.js теперь содержит всю свою функциональность в одном классе:
-class Square {
+class Square {
constructor(ctx, listId, length, x, y, color) {
...
}
@@ -374,15 +374,15 @@ Square.reportPerimeter(square1.length, reportList);
который мы затем экспортируем:
-export { Square };
+export { Square };
Далее в main.js, мы импортируем его так:
-import { Square } from './modules/square.js';
+import { Square } from './modules/square.js';
А затем используем импортированный класс, чтобы нарисовать наш квадрат:
-let square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue');
+let square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue');
square1.draw();
square1.reportArea();
square1.reportPerimeter();
@@ -393,7 +393,7 @@ square1.reportPerimeter();
У вас может быть несколько уровней зависимостей, где вы хотите упростить вещи, объединив несколько подмодулей в один родительский модуль.
Это возможно с использованием следующего синтаксиса экспорта в родительском модуле:
-export * from 'x.js'
+export * from 'x.js'
export { name } from 'x.js'
Для примера посмотрите на нашу директорию module-aggregation.
@@ -402,7 +402,7 @@ export { name } from 'x.js'
Мы также переместили наши подмодули в дочернюю директорию внутри директории modules под названием shape.
Итак, структура модуля в этом примере:
-modules/
+modules/
canvas.js
shapes.js
shapes/
@@ -412,12 +412,12 @@ export { name } from 'x.js'
В каждом из подмодулей экспорт имеет одинаковую форму, например:
-export { Square };
+export { Square };
Далее идет агрегирование.
Внутри shapes.js, мы добавляем следующие строки:
-export { Square } from './shapes/square.js';
+export { Square } from './shapes/square.js';
export { Triangle } from './shapes/triangle.js';
export { Circle } from './shapes/circle.js';
@@ -429,13 +429,13 @@ export { Circle } from './shapes/circle.js';
Итак, теперь в файле main.js мы можем получить доступ ко всем трём классам модулей, заменив:
-import { Square } from './modules/square.js';
+import { Square } from './modules/square.js';
import { Circle } from './modules/circle.js';
import { Triangle } from './modules/triangle.js';
на единственную строку кода:
-import { Square, Circle, Triangle } from './modules/shapes.js';
+import { Square, Circle, Triangle } from './modules/shapes.js';
Динамическая загрузка модулей
@@ -446,7 +446,7 @@ import { Triangle } from './modules/triangle.js';
Поддержка динамической загрузки модулей позволяет вызывать {{JSxRef("Statements/import", "import()", "#Dynamic_Imports")}} в качестве функции, передав ей аргументом путь к модулю.
Данный вызов возвращает {{JSxRef("Promise")}}, который резолвится объектом модуля (см. Создание объекта модуля), предоставляя вам доступ к экспорту указанного модуля, например:
-import('./modules/myModule.js')
+import('./modules/myModule.js')
.then((module) => {
// делаем что-то с функционалом из импортированного модуля
});
@@ -460,11 +460,11 @@ import { Triangle } from './modules/triangle.js';
Далее в main.js мы взяли ссылку на каждую кнопку, используя вызов document.querySelector():
-let squareBtn = document.querySelector('.square');
+let squareBtn = document.querySelector('.square');
Затем мы добавляем обработчик событий на каждую кнопку, чтобы при нажатии соответствующий модуль динамически загружался и использовался для рисования фигуры:
-squareBtn.addEventListener('click', () => {
+squareBtn.addEventListener('click', () => {
import('./modules/square.js').then((Module) => {
let square1 = new Module.Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue');
square1.draw();
diff --git a/files/ru/web/javascript/guide/regular_expressions/character_classes/index.html b/files/ru/web/javascript/guide/regular_expressions/character_classes/index.html
index f9e2b054a3..8a379e7653 100644
--- a/files/ru/web/javascript/guide/regular_expressions/character_classes/index.html
+++ b/files/ru/web/javascript/guide/regular_expressions/character_classes/index.html
@@ -149,7 +149,7 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions/Character_Classes
Поиск серии цифр
-var randomData = "015 354 8787 687351 3512 8735";
+var randomData = "015 354 8787 687351 3512 8735";
var regexpFourDigits = /\b\d{4}\b/g;
// \b определяет границу поиска (например, не начинает поиск с середины слова)
// \d{4} определяет цифру, четыре раза
@@ -162,7 +162,7 @@ console.table(randomData.match(regexpFourDigits));
Поиск слов (латинский алфавит), начинающих с A
-var aliceExcerpt = "I’m sure I’m not Ada,’ she said, ‘for her hair goes in such long ringlets, and mine doesn’t go in ringlets at all.";
+var aliceExcerpt = "I’m sure I’m not Ada,’ she said, ‘for her hair goes in such long ringlets, and mine doesn’t go in ringlets at all.";
var regexpWordStartingWithA = /\b[aA]\w+/g;
// \b определяет границу поиска (например, не начинает поиск с середины слова)
// [aA] определяет букву a или A
@@ -176,7 +176,7 @@ console.table(aliceExcerpt.match(regexpWordStartingWithA));
Вместо латинского алфавита, мы может использовать диапазон Unicode символов для определения слова (благодаря этому мы можем работать с текстами написанным, например на русском или арабском языке or Arabic). Unicode содержит большинство символов используемых на планете, мы так же можем объединять их диапазоны и классы символов.
-var nonEnglishText = "Приключения Алисы в Стране чудес";
+var nonEnglishText = "Приключения Алисы в Стране чудес";
var regexpBMPWord = /([\u0000-\u0019\u0021-\uFFFF])+/gu;
// BMP goes through U+0000 to U+FFFF but space is U+0020
diff --git a/files/ru/web/javascript/guide/regular_expressions/index.html b/files/ru/web/javascript/guide/regular_expressions/index.html
index d6a9f157de..d92683f778 100644
--- a/files/ru/web/javascript/guide/regular_expressions/index.html
+++ b/files/ru/web/javascript/guide/regular_expressions/index.html
@@ -14,7 +14,7 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions
- Используя литерал регулярного выражения, например:
-
var re = /ab+c/;
+ var re = /ab+c/;
@@ -22,7 +22,7 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions
- Вызывая функцию конструктор объекта
RegExp, например:
- var re = new RegExp("ab+c");
+ var re = new RegExp("ab+c");
@@ -321,7 +321,7 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions
Экранирование пользовательского ввода, соответствующего буквенной строке внутри регулярного выражения, может быть достигнуто простой заменой:
-function escapeRegExp(string){
+function escapeRegExp(string){
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
@@ -379,18 +379,18 @@ translation_of: Web/JavaScript/Guide/Regular_Expressions
В след. примере, скрипт использует метод exec чтобы найти совпадения в строке.
-var myRe = /d(b+)d/g;
+var myRe = /d(b+)d/g;
var myArray = myRe.exec("cdbbdbsbz");
Если вам не нужен доступ к свойствам регулярного выражения, то альтернативный способ получить myArray можно так:
-var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+var myArray = /d(b+)d/g.exec("cdbbdbsbz");
Если вы хотите сконструировать регулярное выражение из строки, другой способ сделать это приведён ниже:
-var myRe = new RegExp("d(b+)d", "g");
+var myRe = new RegExp("d(b+)d", "g");
var myArray = myRe.exec("cdbbdbsbz");
@@ -444,25 +444,25 @@ var myArray = myRe.exec("cdbbdbsbz");
Как показано во втором варианте этого примера, вы можете использовать регулярное выражение, созданное при помощи инициализатора объекта, без присваивания его переменной. Таким образом, если вы используете данную форму записи без присваивания переменной, то в процессе дальнейшего использования вы не можете получить доступ к свойствам данного регулярного выражения. Например, у вас есть следующий скрипт:
-var myRe = /d(b+)d/g;
+var myRe = /d(b+)d/g;
var myArray = myRe.exec("cdbbdbsbz");
console.log("The value of lastIndex is " + myRe.lastIndex);
Этот скрипт выведет:
-The value of lastIndex is 5
+The value of lastIndex is 5
Однако, если у вас есть следующий скрипт:
-var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+var myArray = /d(b+)d/g.exec("cdbbdbsbz");
console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
Он выведет:
-The value of lastIndex is 0
+The value of lastIndex is 0
Совпадения /d(b+)d/g в двух случаях являются разными объектами регулярного выражения и, следовательно, имеют различные значения для свойства lastIndex. Если вам необходим доступ к свойствам объекта, созданного при помощи инициализатора, то вы должны сначала присвоить его переменной.
@@ -477,7 +477,7 @@ console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
Следующий скрипт использует метод replace(), чтобы поменять местами слова (символы) в строке. Для замены текста скрипт использует обозначения $1 и $2 для обозначения первого и второго совпадения скобочного выражения.
-var re = /(\w+)\s(\w+)/;
+var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr);
@@ -519,19 +519,19 @@ console.log(newstr);
Чтобы использовать флаги в шаблоне регулярного выражения используйте следующий синтаксис:
-var re = /pattern/flags;
+var re = /pattern/flags;
или
-var re = new RegExp("pattern", "flags");
+var re = new RegExp("pattern", "flags");
Обратите внимание, что флаги являются неотъемлемой частью регулярного выражения. Флаги не могут быть добавлены или удалены позднее.
Для примера, re = /\w+\s/g создаёт регулярное выражение, которое ищет один или более символов, после которых следует пробел и ищет данное совпадение на протяжении всей строки.
-var re = /\w+\s/g;
+var re = /\w+\s/g;
var str = "fee fi fo fum";
var myArray = str.match(re);
console.log(myArray);
@@ -539,12 +539,12 @@ console.log(myArray);
Выведет ["fee ", "fi ", "fo "]. В этом примере вы бы могли заменить строку:
-var re = /\w+\s/g;
+var re = /\w+\s/g;
на следующую:
-var re = new RegExp("\\w+\\s", "g");
+var re = new RegExp("\\w+\\s", "g");
и получить тот же результат.
@@ -559,7 +559,7 @@ console.log(myArray);
След. пример иллюстрирует формирование регулярного выражения и использование string.split() и string.replace(). Он очищает неправильно сформатированную исходную строку, которая содержит имена в неправильном порядке (имя идёт первым) разделённые пробелами, табуляцией и одной точкой с запятой. В конце, изменяется порядок следования имён (фамилия станет первой) и сортируется список.
-// The name string contains multiple spaces and tabs,
+// The name string contains multiple spaces and tabs,
// and may have multiple spaces between first and last names.
var names = "Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ";
@@ -629,7 +629,7 @@ console.log(output.join("\n"));
Событие "Изменить" активируется, когда пользователь подтвердит ввод значения регулярного выражения, нажав клавишу "Enter".
-<!DOCTYPE html>
+<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -655,5 +655,5 @@ console.log(output.join("\n"));
</html>
-autoPreviousNext("JSGChapters");
+autoPreviousNext("JSGChapters");
diff --git a/files/ru/web/javascript/inheritance_and_the_prototype_chain/index.html b/files/ru/web/javascript/inheritance_and_the_prototype_chain/index.html
index 5ed538ca47..eaca7bd05f 100644
--- a/files/ru/web/javascript/inheritance_and_the_prototype_chain/index.html
+++ b/files/ru/web/javascript/inheritance_and_the_prototype_chain/index.html
@@ -23,7 +23,7 @@ translation_of: Web/JavaScript/Inheritance_and_the_prototype_chain
Объекты в JavaScript — динамические "контейнеры", наполненные свойствами (называемыми собственными свойствами). Каждый объект содержит ссылку на свой объект-прототип.
При попытке получить доступ к какому-либо свойству объекта, свойство вначале ищется в самом объекте, затем в прототипе объекта, после чего в прототипе прототипа, и так далее. Поиск ведётся до тех пор, пока не найдено свойство с совпадающим именем или не достигнут конец цепочки прототипов.
-// В этом примере someObject.[[Prototype]] означает прототип someObject.
+// В этом примере someObject.[[Prototype]] означает прототип someObject.
// Это упрощённая нотация (описанная в стандарте ECMAScript).
// Она не может быть использована в реальных скриптах.
@@ -74,7 +74,7 @@ console.log(o.d); // undefined
В области видимости унаследованной функции ссылка this указывает на наследующий объект (на наследника), а не на прототип, в котором данная функция является собственным свойством.
-var o = {
+var o = {
a: 2,
m: function(){
return this.a + 1;
@@ -98,7 +98,7 @@ console.log(p.m()); // 13
Создание объектов с помощью литералов
-var o = {a: 1};
+var o = {a: 1};
// Созданный объект 'o' имеет Object.prototype в качестве своего [[Prototype]]
// у 'o' нет собственного свойства 'hasOwnProperty'
@@ -127,7 +127,7 @@ function f(){
В JavaScript "конструктор" — это "просто" функция, вызываемая с оператором new.
-function Graph() {
+function Graph() {
this.vertexes = [];
this.edges = [];
}
@@ -147,7 +147,7 @@ var g = new Graph();
В ECMAScript 5 представлен новый метод создания объектов: Object.create. Прототип создаваемого объекта указывается в первом аргументе этого метода:
-var a = {a: 1};
+var a = {a: 1};
// a ---> Object.prototype ---> null
var b = Object.create(a);
@@ -168,7 +168,7 @@ console.log(d.hasOwnProperty);
С выходом ECMAScript 6 появился целый набор ключевых слов, реализующих классы. Они могут показаться знакомыми людям, изучавшим языки, основанные на классах, но есть существенные отличия. JavaScript был и остаётся прототипно-ориентированным языком. Новые ключевые слова: "class", "constructor", "static", "extends" и "super".
-"use strict";
+"use strict";
class Polygon {
constructor(height, width) {
@@ -217,7 +217,7 @@ var square = new Square(2);
B наследует от A:
-function A(a){
+function A(a){
this.varA = a;
}
@@ -274,17 +274,17 @@ b.doSomething();
[[Prototype]] работает рекурсивно, то есть при вызове:
-var o = new Foo();
+var o = new Foo();
JavaScript на самом деле выполняет что-то подобное:
-var o = new Object();
+var o = new Object();
o.[[Prototype]] = Foo.prototype;
Foo.call(o);
а когда вы делаете так:
-o.someProp;
+o.someProp;
JavaScript проверяет, есть ли у o свойство someProp.
и если нет, то проверяет Object.getPrototypeOf(o).someProp
diff --git a/files/ru/web/javascript/memory_management/index.html b/files/ru/web/javascript/memory_management/index.html
index 4fa942b997..4399b25d64 100644
--- a/files/ru/web/javascript/memory_management/index.html
+++ b/files/ru/web/javascript/memory_management/index.html
@@ -28,7 +28,7 @@ translation_of: Web/JavaScript/Memory_Management
Чтобы не утруждать программиста заботой о низкоуровневых операциях выделения памяти, интерпретатор JavaScript динамически выделяет необходимую память при объявлении переменных: