From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- .../functions/arguments/callee/index.html | 141 ++++++ .../functions/arguments/caller/index.html | 100 +++++ .../reference/functions/arguments/index.html | 241 ++++++++++ .../functions/arguments/length/index.html | 117 +++++ .../reference/functions/arrow_functions/index.html | 378 ++++++++++++++++ .../functions/default_parameters/index.html | 217 +++++++++ .../javascript/reference/functions/get/index.html | 180 ++++++++ .../web/javascript/reference/functions/index.html | 483 +++++++++++++++++++++ .../reference/functions/rest_parameters/index.html | 209 +++++++++ .../javascript/reference/functions/set/index.html | 134 ++++++ .../index.html" | 191 ++++++++ 11 files changed, 2391 insertions(+) create mode 100644 files/ru/web/javascript/reference/functions/arguments/callee/index.html create mode 100644 files/ru/web/javascript/reference/functions/arguments/caller/index.html create mode 100644 files/ru/web/javascript/reference/functions/arguments/index.html create mode 100644 files/ru/web/javascript/reference/functions/arguments/length/index.html create mode 100644 files/ru/web/javascript/reference/functions/arrow_functions/index.html create mode 100644 files/ru/web/javascript/reference/functions/default_parameters/index.html create mode 100644 files/ru/web/javascript/reference/functions/get/index.html create mode 100644 files/ru/web/javascript/reference/functions/index.html create mode 100644 files/ru/web/javascript/reference/functions/rest_parameters/index.html create mode 100644 files/ru/web/javascript/reference/functions/set/index.html create mode 100644 "files/ru/web/javascript/reference/functions/\320\276\320\277\321\200\320\265\320\264\320\265\320\273\320\270\320\275\320\270\320\265_\320\274\320\265\321\202\320\276\320\264\320\276\320\262/index.html" (limited to 'files/ru/web/javascript/reference/functions') diff --git a/files/ru/web/javascript/reference/functions/arguments/callee/index.html b/files/ru/web/javascript/reference/functions/arguments/callee/index.html new file mode 100644 index 0000000000..eaf41af79d --- /dev/null +++ b/files/ru/web/javascript/reference/functions/arguments/callee/index.html @@ -0,0 +1,141 @@ +--- +title: arguments.callee +slug: Web/JavaScript/Reference/Functions/arguments/callee +translation_of: Web/JavaScript/Reference/Functions/arguments/callee +--- +
{{jsSidebar("Functions")}}
+ +

Свойство callee псевдомассива arguments хранит ссылку на функцию-родитель.

+ +

Описание

+ +
Внимание: В ES5 strict mode использование arguments.callee запрещено.
+ +

Зачем вообще использовать arguments.callee?

+ +

В ранних версиях javaScript отсутствовала такая фишка, как Named Function Expression и единственным спасением было свойство callee. К примеру:

+ +
var f = function test() {
+    alert(typeof test); //undefined
+    alert(typeof arguments.callee); //function
+}
+
+ +

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

+ +
var f = function test(){
+   alert(typeof test); //function
+}
+ +

 

+ +

Действительно незаменимым оно остается всего в одной ситуации. Когда мы создаем анонимную функцию напрямую через конструктор Function.

+ +
var b = new Function("", "alert(typeof arguments.callee)");
+ +

 

+ +

Пример использования

+ +

 

+ +

Использование arguments.callee для создания рекурсии

+ +
var factorial = function(n) {
+  return n == 1 ? 1 : n * arguments.callee(n-1);
+};
+
+factorial(7);
+
+ +

 

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.2
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}} 
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

See also

+ + diff --git a/files/ru/web/javascript/reference/functions/arguments/caller/index.html b/files/ru/web/javascript/reference/functions/arguments/caller/index.html new file mode 100644 index 0000000000..0b6fe5cc4b --- /dev/null +++ b/files/ru/web/javascript/reference/functions/arguments/caller/index.html @@ -0,0 +1,100 @@ +--- +title: arguments.caller +slug: Web/JavaScript/Reference/Functions/arguments/caller +tags: + - Functions + - JavaScript + - Obsolete + - Property + - arguments +translation_of: Archive/Web/JavaScript/arguments.caller +--- +
{{jsSidebar("Functions")}}
+ +

Устаревшее свойство arguments.caller использовалось для того, чтобы определить источник вызова функции, выполняющейся в текущий момент времени. Данное свойство было удалено и больше не работает.

+ +

Описание

+ +

Данное свойство больше не доступно, но вы все так же можете использовать {{jsxref("Function.caller")}}.

+ +
function whoCalled() {
+   if (whoCalled.caller == null)
+      console.log('Меня вызвали из глобальной области видимости.');
+   else
+      console.log(whoCalled.caller + ' вызвал меня!');
+}
+ +

Примеры

+ +

Код, приведенный ниже, больше не работает, но раньше он использовался для проверки значения arguments.caller функции.

+ +
function whoCalled() {
+   if (arguments.caller == null)
+      console.log('Меня вызвали из глобальной области видимости.');
+   else
+      console.log(arguments.caller + ' вызвал меня!');
+}
+
+ +

Спецификации

+ +

Не является частью какого-либо стандарта. Реализовано в JavaScript 1.1 и удалено в {{bug(7224)}}, поскольку влекло за собой потенциальную уязвимость.

+ +

Совместимость с браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Базовая поддержка{{CompatNo}}{{CompatNo}}{{CompatNo}}
+ удалено в IE 9
{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Базовая поддержка{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

Смотрите также

+ + diff --git a/files/ru/web/javascript/reference/functions/arguments/index.html b/files/ru/web/javascript/reference/functions/arguments/index.html new file mode 100644 index 0000000000..13ef8edd8d --- /dev/null +++ b/files/ru/web/javascript/reference/functions/arguments/index.html @@ -0,0 +1,241 @@ +--- +title: Объект arguments +slug: Web/JavaScript/Reference/Functions/arguments +tags: + - Functions + - JavaScript + - Reference + - arguments +translation_of: Web/JavaScript/Reference/Functions/arguments +--- +
+
{{jsSidebar("Functions")}}
+
+ +

Объект arguments — это подобный массиву объект, который содержит аргументы, переданные в функцию.

+ +
+

Примечание: Если вы пишите ES6-совместимый код, то лучше использовать rest параметры.

+
+ +
+

Примечание: "Подобный массиву" означает, что arguments имеет свойство {{jsxref("Functions/arguments/length", "length")}}, а элементы индексируются начиная с нуля. Но при это он не может обращаться к встроенным методам {{JSxRef("Array")}}, таким как {{jsxref("Array.forEach", "forEach()")}} или {{jsxref("Array.map", "map()")}}. Подробнее об этом в §Описании.

+
+ +

{{EmbedInteractiveExample("pages/js/functions-arguments.html")}}

+ + + +

Синтаксис

+ +
arguments
+ +

Описание

+ +

Объект arguments — это локальная переменная, доступная внутри любой (нестрелочной) функции. Объект arguments позволяет ссылаться на аргументы функции внутри неё. Он состоит из переданных в функцию аргументов, индексация начинается с 0. Например, если в функцию было передано 3 аргумента, обратиться к ним можно следующим образом:

+ +
arguments[0]
+arguments[1]
+arguments[2]
+
+ +

Аргументам может быть присвоено значение:

+ +
arguments[1] = 'new value';
+ +

Объект arguments не является {{jsxref("Array")}}. Он похож на массив, но не обладает ни одним из его свойств, кроме length. Например, у него нет метода pop. Однако он может быть преобразован в обычный массив:

+ +
var args = Array.prototype.slice.call(arguments);
+var args = [].slice.call(arguments);
+
+// ES2015
+const args = Array.from(arguments);
+const args = [...arguments];
+
+ +
+

Использование slice на объекте arguments не позволяет сделать оптимизации в некоторых JavaScript движках (например, V8 — подробнее). Если они важны, можно попробовать вместо этого создать новый массив с аналогичной длиной и заполнить его элементами объекта arguments. Альтернативный вариант — использовать конструктор Array как функцию:

+ +
var args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));
+
+ +

Объект arguments можно использовать при вызове функции с большим количеством аргументов, чем было предусмотрено в её объявлении. Такой способ удобен для функций, в которые допустимо передавать переменное количество аргументов. Можно воспользоваться arguments.length, чтобы определить количество переданных в функцию аргументов, а затем обработать каждый из них с помощью объекта arguments. Чтобы определить количество параметров функции, описанных в её сигнатуре, можно использовать свойство Function.length.

+ +

Использование typeof с объектом arguments

+ +

Применение оператора typeof к arguments вернёт 'object'.

+ +
console.log(typeof arguments); // 'object'
+ +

Определение типов аргументов может быть выполнено применением оператора typeof и индексацией.

+ +
// выведет тип первого аргумента
+console.log(typeof arguments[0]);
+ +

Использование оператора расширения для объекта arguments

+ +

Как и с обычными массиво-подобными объектами, для преобразования объекта arguments в обычный массив можно использовать метод {{jsxref("Array.from()")}} или оператор расширения:

+ +
var args = Array.from(arguments);
+var args = [...arguments];
+ +

Свойства

+ +
+
arguments.callee
+
Ссылка на функцию, которая выполняется в текущий момент.
+
arguments.caller {{ Obsolete_inline() }}
+
Ссылка на функцию, которая вызвала функцию, выполняющуюся в текущий момент.
+
arguments.length
+
Количество переданных в функцию аргументов.
+
arguments[@@iterator]
+
Возвращает новый объект Array Iterator, содержащий значения для каждого индекса в массиве.
+
+ +

Примеры

+ +

Создание функции, соединяющей несколько строк

+ +

Данный пример описывает функцию, которая соединяет несколько строк. Для этой функции объявлен только один аргумент, определяющий символ-разделитель соединяемых элементов. Функция определена следующим образом:

+ +
function myConcat(separator) {
+  var args = Array.prototype.slice.call(arguments, 1);
+  return args.join(separator);
+}
+ +

Вы можете передать любое количество аргументов в эту функцию. Она создает строку, используя каждый аргумент:

+ +
// возвращает "red, orange, blue"
+myConcat(", ", "red", "orange", "blue");
+
+// получает "elephant; giraffe; lion; cheetah"
+myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
+
+// выводит "sage. basil. oregano. pepper. parsley"
+myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
+ +

 Функция, создающая HTML списки

+ +

В данном примере приведена функция, которая создает строку с HTML-разметкой для списка. Единственный ее аргумент - строка, определяющая вид списка: если его значение равно "u", формируется неупорядоченный (маркированный) список, а если "o", то упорядоченный (нумерованный):

+ +
function list(type) {
+  var result = "<" + type + "l><li>";
+  var args = Array.prototype.slice.call(arguments, 1);
+  result += args.join("</li><li>");
+  result += "</li></" + type + "l>"; // конец списка
+
+  return result;
+}
+ +

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

+ +
var listHTML = list("u", "One", "Two", "Three");
+
+/* listHTML:
+
+"<ul><li>One</li><li>Two</li><li>Three</li></ul>"
+
+*/
+ +

Оставшиеся, деструктурированные и параметры по умолчанию

+ +

Объект arguments может использоваться совместно с оставшимися параметрами, параметрами по умолчанию или деструктурированными параметрами.

+ +
function foo(...args) {
+  return arguments;
+}
+foo(1, 2, 3); // { "0": 1, "1": 2, "2": 3 }
+ +

Тем не менее, в нестрогих функциях соответствие между их аргументами и объектом arguments существует только в том случае, если функция не содержит никаких оставшихся параметров, параметров по умолчанию или деструктурированных параметров. Например, в функции, приведенной ниже, используется параметр по умолчанию, и в данном случае возвращаемый результат будет равен 10, а не 100:

+ +
function bar(a=1) {
+  arguments[0] = 100;
+  return a;
+}
+bar(10); // 10
+ +

В следующем примере возвращается 100, поскольку здесь нет оставшихся параметров, параметров по умолчанию или деструктурированных параметров:

+ +
function zoo(a) {
+  arguments[0] = 100;
+  return a;
+}
+zoo(10); // 100
+ +

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

+ +
function func(a, b) {
+    arguments[0] = 90;
+    arguments[1] = 99;
+    console.log(a + " " + b);
+}
+
+func(1, 2); //90, 99
+ +

или

+ +
function func(a, b) {
+    a = 9;
+    b = 99;
+    console.log(arguments[0] + " " + arguments[1]);
+}
+
+func(3, 4); //9, 99
+ +

Но в случае, когда применяются оставшиеся параметры, параметры по умолчанию или деструктурированные параметры, будет обработано нормальное поведение, как в случае параметров по умолчанию:

+ +
function func(a, b, c=9) {
+    arguments[0] = 99;
+    arguments[1] = 98;
+    console.log(a + " " + b);
+}
+
+func(3, 4); //3, 4
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКоментарии
{{SpecName('ES1')}}{{Spec2('ES1')}}Изначальное определение. Реализовано в JavaScript 1.1
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}}
+ +

Поддержка браузерами

+ + + +

{{Compat("javascript.functions.arguments")}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/javascript/reference/functions/arguments/length/index.html b/files/ru/web/javascript/reference/functions/arguments/length/index.html new file mode 100644 index 0000000000..4411d266e5 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/arguments/length/index.html @@ -0,0 +1,117 @@ +--- +title: arguments.length +slug: Web/JavaScript/Reference/Functions/arguments/length +translation_of: Web/JavaScript/Reference/Functions/arguments/length +--- +
{{jsSidebar("Functions")}}
+ +

arguments.length  свойство, содержащее число аргументов переданных в функцию.

+ +

Синтаксис

+ +
arguments.length
+ +

Описание

+ +

arguments.length свойство содержашее число аргументов переданных в функцию. Оно может быть больше или меньше опреденного параметра count (см. {{jsxref("Function.length")}}).

+ +

Примеры

+ +

Использование arguments.length

+ +

В этом примере мы определяем функцию, которая может сложить 2 или более чисел вместе.

+ +
function adder(base /*, n2, ... */) {
+  base = Number(base);
+  for (var i = 1; i < arguments.length; i++) {
+    base += Number(arguments[i]);
+  }
+  return base;
+}
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.1
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES6')}} 
+ +

Поддержка браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Смотрите также

+ + diff --git a/files/ru/web/javascript/reference/functions/arrow_functions/index.html b/files/ru/web/javascript/reference/functions/arrow_functions/index.html new file mode 100644 index 0000000000..b903c96852 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/arrow_functions/index.html @@ -0,0 +1,378 @@ +--- +title: Стрелочные функции +slug: Web/JavaScript/Reference/Functions/Arrow_functions +tags: + - ECMAScript6 + - JavaScript + - Функции +translation_of: Web/JavaScript/Reference/Functions/Arrow_functions +--- +
{{jsSidebar("Functions")}}
+ +

Сводка

+ +

Выражения стрелочных функций имеют более короткий синтаксис по сравнению с функциональными выражениями и лексически привязаны к значению this (но не привязаны к собственному thisargumentssuper, или new.target). Выражение стрелочных функций не позволяют задавать имя, поэтому стрелочные функции анонимны, если их ни к чему не присвоить.

+ +

Синтаксис

+ +

Базовый синтаксис

+ +
(param1, param2, …, paramN) => { statements }
+(param1, param2, …, paramN) => expression
+// эквивалентно: (param1, param2, …, paramN) => { return expression; }
+
+// Круглые скобки не обязательны для единственного параметра:
+(singleParam) => { statements }
+singleParam => { statements }
+
+// Функция без параметров нуждается в круглых скобках:
+() => { statements }
+() => expression
+// Эквивалентно: () => { return expression; }
+
+ +

Расширенный синтаксис

+ +
// Когда возвращаете литеральное выражение объекта, заключите тело в скобки
+params => ({foo: bar})
+
+// Rest параметры и параметры по умолчанию поддерживаются
+(param1, param2, ...rest) => { statements }
+(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
+
+// Деструктуризация тоже поддерживается
+var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
+f();  // 6
+
+ +

Подробные примеры синтаксиса можно посмотреть здесь.

+ +

Описание

+ +

Смотрите также "ES6 In Depth: Arrow functions" on hacks.mozilla.org.

+ +

Два фактора повлияли на появление стрелочных функции: более короткий синтаксис и лексика this.

+ +

Короткие функции

+ +

В некоторых функциональных шаблонах приветствуются более короткие функции. Сравните:

+ +
var elements = [
+  'Hydrogen',
+  'Helium',
+  'Lithium',
+  'Beryllium'
+];
+
+elements.map(function(element) {
+  return element.length;
+}); // Это выражение вернет массив [8, 6, 7, 9]
+
+// Функцию выше можно записать как стрелочную функцию:
+elements.map((element) => {
+  return element.length;
+}); // [8, 6, 7, 9]
+
+// Если единственным оператором в выражении стрелочной функции является return,
+// можно удалить return и окружающие фигурные скобки
+
+elements.map(element => element.length); // [8, 6, 7, 9]
+
+// В данном случае, поскольку нам нужно только свойство length, мы можем использовать деструктуризированный параметр:
+// Обратите внимание, что строка `"length"` соответствует свойству, которое мы хотим получить,
+// в то время как `lengthFooBArX` это просто имя переменной, которую можно назвать как вы хотите
+elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]
+
+// Это задание деструктуризированного параметра может быть записано, как показано ниже. Тем не менее, обратите внимание,
+// что нет строки `"length"`, чтобы выбрать, какое свойство мы хотим получить. Вместо этого в качестве свойства,
+// которое мы хотим извлечь из объекта, используется само литеральное имя переменной `length`
+elements.map(({ length }) => length); // [8, 6, 7, 9]
+
+ +

Отсутствие связывания с this

+ +

До появления стрелочных функций, каждая новая функция имела своё значение this (новый объект в случае конструктора, undefined в strict режиме вызова функции, контекст объекта при вызове функции как "метода объекта" и т.д.). Это очень раздражало при использовании объектно-ориентированного стиля программирования.

+ +
function Person() {
+  // В конструкторе Person() `this` указывает на себя.
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // В нестрогом режиме, в функции growUp() `this` указывает
+    // на глобальный объект, который отличается от `this`,
+    // определяемом в конструкторе Person().
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+
+ +

В ECMAScript 3/5, данная проблема решалась присваиванием значения this переменной:

+ +
function Person() {
+  var that = this;
+  that.age = 0;
+
+  setInterval(function growUp() {
+    // Функция с обратным вызовом(callback) содержит переменную that, которая
+    // ссылается на требуемый объект this.
+    that.age++;
+  }, 1000);
+}
+ +

Кроме этого, может быть создана привязанная функция, в которую передаётся требуемое значение this для функции (функция growUp() в примере выше).

+ +

Стрелочные функции не содержат собственный контекст this, а используют значение this окружающего контекста. Поэтому нижеприведенный код работает как предполагалось:

+ +
function Person(){
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // `this` указывает на объект Person
+  }, 1000);
+}
+
+var p = new Person();
+ +

Строгий режим исполнения

+ +

Поскольку значение this определяется лексикой, правила строгого режима (strict mode) относительно this игнорируются:

+ +
var f = () => { 'use strict'; return this; };
+f() === window; // или глобальный объект
+ +

Все остальные правила строгого режима применяются как обычно.

+ +

Вызов с помощью call или apply

+ +

Так как значение this определяется лексикой, вызов стрелочных функций с помощью методов call() или apply(), даже если передать аргументы в эти методы, не влияет на значение this:

+ +
var adder = {
+  base : 1,
+
+  add : function(a) {
+    var f = v => v + this.base;
+    return f(a);
+  },
+
+  addThruCall: function(a) {
+    var f = v => v + this.base;
+    var b = {
+      base : 2
+    };
+
+    return f.call(b, a);
+  }
+};
+
+console.log(adder.add(1));         // Выводит 2
+console.log(adder.addThruCall(1)); // Всё равно выводит 2
+
+ +

Не имеет собственного объекта arguments

+ +

Стрелочные функции не имеют собственного объекта arguments, поэтому в теле стрелочных функций arguments будет ссылаться на переменную в окружающей области.

+ +
var arguments = 42;
+var arr = () => arguments;
+
+arr(); // 42
+
+function foo() {
+  var f = (i) => arguments[0] + i; // Неявное связывание ссылки arguments
+                                   // стрелочной функции f
+                                   // c объектом arguments функции foo
+  return f(2);
+}
+
+foo(1); // 3
+ +

В большинстве случаев лучшей заменой объекта arguments в стрелочных функциях являются rest параметры:

+ +
function foo() {
+  var f = (...args) => args[0];
+  return f(2);
+}
+
+foo(1); // 2
+
+ +

Использование стрелочных функций как методов

+ +

Как показано ранее, стрелочные функции лучше всего подходят для функций без методов. Посмотрим, что будет, когда мы попробуем их использовать как методы:

+ +
'use strict';
+var obj = {
+  i: 10,
+  b: () => console.log(this.i, this),
+  c: function() {
+    console.log(this.i, this);
+  }
+}
+obj.b(); // prints undefined, Window {...} (или глобальный объект)
+obj.c(); // prints 10, Object {...}
+
+ +

Стрелочные функции не объявляют привязку ("bind") их контекста this. Другой пример включает {{jsxref("Object.defineProperty()")}}:

+ +
'use strict';
+var obj = {
+  a: 10
+};
+
+Object.defineProperty(obj, 'b', {
+  get: () => {
+    console.log(this.a, typeof this.a, this);
+    return this.a + 10;
+    // представляет глобальный объект 'Window', но 'this.a' возвращает 'undefined'
+  }
+});
+ +

Использование оператора new

+ +

Стрелочные функции не могут быть использованы как конструктор и вызовут ошибку при использовании с new:

+ +
var a = new (function() {})
+// переменной "a" будет присвоено значение экземпляра анонимной функции
+
+var b = new (() => {})
+// будет выброшено исключениe
+// Uncaught TypeError: (intermediate value) is not a constructor
+ +

Использование ключевого слова yield

+ +

Ключевое слово yield не может быть использовано в теле стрелочной функции (за исключением случаев, когда разрешается использовать в функциях, вложенных в тело стрелочной функции). Как следствие стрелочные функции не могут быть использованы как генераторы.

+ +

Тело функции

+ +

Тело стрелочной функции может иметь краткую (concise body) или блочную (block body) форму.

+ +

Блочная форма не возвращает значение, необходимо явно вернуть значение.

+ +
var func = x => x * x;                  // краткий синтаксис,
+                                        // неявно возвращает результат
+var func = (x, y) => { return x + y; }; // блочный синтаксис,
+                                        // явно возвращает результат
+ +

Возвращаемые объектные строки (литералы)

+ +

Помните о том, что возвращаемые объектные строки используют сокращённый синтаксис: params => {object:literal} будет работать не так, как ожидается.

+ +
var func = () => { foo: 1 };
+// Вызов func() возвращает undefined!
+
+var func = () => { foo: function() {} };
+// SyntaxError: function statement requires a name
+ +

Это происходит потому что код в скобках ({}) распознаётся как цепочка выражений (т.е. foo трактуется как наименование, а не как ключ в объектной строке).

+ +

Не забывайте оборачивать скобками объектные строки.

+ +
var func = () => ({ foo: 1 });
+ +

Разрывы строк

+ +

Стрелочная функция не может содержать разрывы строк между параметрами и стрелкой.

+ +
var func = ()
+           => 1;
+// SyntaxError: expected expression, got '=>'
+
+ +

Разбор порядка следования

+ +

Поскольку стрелка в стрелочной функции не является оператором, то стрелочные функции имеют специальные правила разбора (парсинга), которые взаимодействуют с приоритетами операторов  иначе, чем в обычных функциях.

+ +
let callback;
+
+callback = callback || function() {}; // ok
+
+callback = callback || () => {};
+// SyntaxError: invalid arrow-function arguments
+
+callback = callback || (() => {});    // ok
+
+ +

Больше примеров

+ +
// Пустая стрелочная функция возвращает undefined
+let empty = () => {};
+
+(() => 'foobar')();
+// Вернёт "foobar"
+// (Это Immediately Invoked Function Expression
+// смотри 'IIFE' в справочнике)
+
+var simple = a => a > 15 ? 15 : a;
+simple(16); // 15
+simple(10); // 10
+
+let max = (a, b) => a > b ? a : b;
+
+// Удобные операции над массивами: filter, map, ...
+
+var arr = [5, 6, 13, 0, 1, 18, 23];
+
+var sum = arr.reduce((a, b) => a + b);
+// 66
+
+var even = arr.filter(v => v % 2 == 0);
+// [6, 0, 18]
+
+var double = arr.map(v => v * 2);
+// [10, 12, 26, 0, 2, 36, 46]
+
+// Более короткие цепочки promise-ов
+promise.then(a => {
+  // ...
+}).then(b => {
+   // ...
+});
+
+// Стрелочные функции без параметров, которые визуально легче разбирать
+setTimeout( () => {
+  console.log('Я буду раньше');
+  setTimeout( () => {
+    // deeper code
+    console.log('Я буду позже');
+  }, 1);
+}, 1);
+
+ +

Спецификации

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES6', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ES6')}}Изначальное определение.
+ +

Совместимость с браузерами

+ + + +

{{Compat("javascript.functions.arrow_functions")}}

+ +

Замечания для Firefox

+ + + +

See also

+ + diff --git a/files/ru/web/javascript/reference/functions/default_parameters/index.html b/files/ru/web/javascript/reference/functions/default_parameters/index.html new file mode 100644 index 0000000000..2e6568b816 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/default_parameters/index.html @@ -0,0 +1,217 @@ +--- +title: Параметры по умолчанию +slug: Web/JavaScript/Reference/Functions/Default_parameters +tags: + - ECMAScript6 + - JavaScript + - Функции + - Экспериментальный +translation_of: Web/JavaScript/Reference/Functions/Default_parameters +--- +
{{jsSidebar("Functions")}}
+ +

Параметры по умолчанию позволяют задавать формальным параметрам функции значения по умолчанию в случае, если функция вызвана без аргументов, или если параметру явным образом передано значение undefined.

+ +

{{EmbedInteractiveExample("pages/js/functions-default.html")}}

+ +

Синтаксис

+ +
function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
+   statements
+}
+
+ +

Описание

+ +

В JavaScript параметры функции, которым при ее вызове не передаются значения, принимают по умолчанию значение {{jsxref("undefined")}}. Однако в некоторых случаях может быть полезно задать иное значение по умолчанию. Именно для таких случаев предназначены параметры по умолчанию.

+ +

В прошлом для проверки параметров и задания их значений по умолчанию использовался код в теле функции, в котором проверялось, не равны ли значения параметров undefined.

+ +

В приведённом ниже примере, в случае если при вызове функции значение для параметра b не передавалось, его значением становилось undefined,  и результатом вычисления a * b в функции multiply получалось значение NaN.

+ +
function multiply(a, b) {
+  return a * b;
+}
+
+multiply(5, 2); // 10
+multiply(5);    // NaN !
+ +

Чтобы такого не происходило, в теле функции использовался код подобный тому, что находится во второй строчке, где в случае, если функция multiply вызывалась только c одним аргументом, параметру b присваивалось значение 1:

+ +
function multiply(a, b) {
+  b = typeof b !== 'undefined' ?  b : 1;
+  return a*b;
+}
+
+multiply(5, 2); // 10
+multiply(5); // 5
+
+ +

С появлением в ES2015 параметров по умолчанию стало возможным обходиться без проверки параметров в теле функции. Так, в приведенном выше примере достаточно в заголовке функции указать 1 в качестве значения по умолчанию для параметра b:

+ +
function multiply(a, b = 1) {
+  return a*b;
+}
+
+multiply(5, 2); // 10
+multiply(5); // 5
+multiply(5, undefined); // 5
+ +

Примеры

+ +

Передача значения undefined в сравнении с передачей других "ложных" значений

+ +

Значение по умолчанию присваивается формальному параметру только если при вызове функции значение для данного параметра не было передано или было явным образом передано undefined. Если формальному параметру при вызове передано любое значение, отличное от undefined, в том числе одно из "ложных" значений, таких как false, 0, "", '', ``, null, NaN, то в этом случае значение по умолчанию присвоено параметру не будет.  Это иллюстрирует следующий пример:

+ +
function test(num = 1) {
+  console.log(typeof num);
+}
+
+// num не прередано, или передано undefined:
+test();          // 'number' (num получил значение 1)
+test(undefined); // 'number' (и здесь num получил значение 1)
+
+// num передано значение null или другое "ложное" значение:
+test('');        // 'string' (num получил значение '')
+test(null);      // 'object' (num получил значение null)
+
+ +

Параметры по умолчанию вычисляются в момент вызова функции

+ +

В Javascript параметры по умолчанию вычисляются в момент вызова функции. В отличие от языка Python, при каждом вызове функции создается новое лексическое окружение функции.

+ +
function append(value, array = []) {
+  array.push(value);
+  return array;
+}
+
+append(1); // [1]
+append(2); // [2], а не [1, 2]
+
+
+ +

Это верно и для функций, и для переменных:

+ +
function callSomething(thing = something()) {
+ return thing;
+}
+
+let numberOfTimesCalled = 0;
+function something() {
+  numberOfTimesCalled += 1;
+  return numberOfTimesCalled;
+}
+
+callSomething(); // 1
+callSomething(); // 2
+
+ +

Параметры по умолчанию доступны в следующих параметрах по умолчанию

+ +

В параметрах по умолчанию можно использовать значения предыдущих (расположеннных левее в списке) параметров:

+ +
function greet(name, greeting, message = greeting + ' ' + name) {
+    return [name, greeting, message];
+}
+
+greet('David', 'Hi');  // ["David", "Hi", "Hi David"]
+greet('David', 'Hi', 'Happy Birthday!');  // ["David", "Hi", "Happy Birthday!"]
+ +

Следующий пример пример еще раз иллюстирует эту возможность, а также позволяет еще раз сравнить два способа достижения одного и того же результата: с использованием инициализации параметров по умолчанию и без ее использования:

+ +
function go() {
+  return ":P"
+}
+
+function withDefaults(a, b = 5, c = b, d = go(), e = this,
+                      f = arguments, g = this.value) {
+  return [a,b,c,d,e,f,g];
+}
+function withoutDefaults(a, b, c, d, e, f, g){
+  switch(arguments.length){
+    case 0:
+      a
+    case 1:
+      b = 5
+    case 2:
+      c = b
+    case 3:
+      d = go();
+    case 4:
+      e = this
+    case 5:
+      f = arguments
+    case 6:
+      g = this.value;
+    default:
+  }
+  return [a,b,c,d,e,f,g];
+}
+
+withDefaults.call({value:"=^_^="});
+// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
+
+
+withoutDefaults.call({value:"=^_^="});
+// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
+
+ +

Инициализация с помощью функций, определяемых в теле функции

+ +

Начиная с версии Gecko 33 {{geckoRelease(33)}} функции, определяемые в теле самой функции, не могут быть использованы для инициализации параметров по умолчанию; попытка это сделать приведет к ошибке {{jsxref("ReferenceError")}}. Параметры по умолчанию всегда вычисляются до обработки описаний функций, определяемых в теле функции.

+ +
// Вызовет ошибку ReferenceError!
+function f(a = go()) {
+  function go(){return ":P"}
+}
+f(); // ReferenceError: go is not defined
+
+ +

Параметры без инициализации, следующие после инициализируемых параметров

+ +

До появления версии Gecko 26 {{geckoRelease(26)}}, следующий код приводил к {{jsxref("SyntaxError")}}. Это было исправлено в {{bug(777060)}} и с тех пор работает корректно. Аргументы, передаваемые при вызове функции, становятся значениями формальных параметров независимо от наличия у последних инициализации по умолчанию, а также независимо от присутствия у функции других параметров, находящихся правее в списке параметров и не имеющих инициализации.

+ +
function f(x=1, y) {
+  return [x, y];
+}
+
+f(); // [1, undefined];
+f(2); // [2, undefined];
+
+ +

Инициализация по умолчанию деструктурированных параметров

+ +

При инициализации параметров по умолчанию можно использовать синтаксическую конструкцию деструктурирующего присваивания:

+ +
function f([x, y] = [1, 2], {z: z} = {z: 3}) {
+  return x + y + z;
+}
+
+f(); // 6
+ +

Спецификации

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES6', '#sec-function-definitions', 'Определение функций')}}{{Spec2('ES6')}}Изначальное определение.
+ +

Совместимость с браузерами

+ +

{{Compat("javascript.functions.default_parameters")}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/javascript/reference/functions/get/index.html b/files/ru/web/javascript/reference/functions/get/index.html new file mode 100644 index 0000000000..9e2c329c8e --- /dev/null +++ b/files/ru/web/javascript/reference/functions/get/index.html @@ -0,0 +1,180 @@ +--- +title: getter +slug: Web/JavaScript/Reference/Functions/get +tags: + - геттер +translation_of: Web/JavaScript/Reference/Functions/get +--- +
{{jsSidebar("Functions")}}
+ +

Синтаксис get связывает свойство объекта с функцией, которая будет вызываться при обращении к этому свойству.

+ +
{{EmbedInteractiveExample("pages/js/functions-getter.html")}}
+ + + +

Синтаксис

+ +
{get prop() { ... } }
+{get [expression]() { ... } }
+ +

Параметры

+ +
+
prop
+
Имя свойства для привязывания к заданной функции.
+
expression
+
Начиная с ECMAScript 6, Вы также можете использовать выражения для вычисляемого имени свойства для привязки к заданной функции.
+
+ +

Описание

+ +

Иногда желательно разрешить доступ к свойству, которое возвращает динамически вычисляемое значение, или Вы можете захотеть отражать состояние внутренней переменной без необходимости использования явных вызовов методов. В JavaScript, это можно реализовать при помощи использования геттера.

+ +

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

+ +

Учтите следующее при работе с синтаксисом get:

+ +
+ +
+ +

Геттер можно удалить при помощи оператора delete.

+ +

Примеры

+ +

Определение геттера на новом объекте в момент инициализации этого объекта

+ +

Ниже создается псевдо-свойство latest для объекта obj, который выведет последний элемент массива в консоль лог.

+ +
const obj = {
+  log: ['example','test'],
+  get latest() {
+    if (this.log.length === 0) return undefined;
+    return this.log[this.log.length - 1];
+  }
+}
+console.log(obj.latest); // "test"
+
+ +

Обратите внимание, что попытка присвоить значение latest не изменит его.

+ +

Удаление геттера оператором delete

+ +

Если Вы хотите удалить геттер, используйте delete:

+ +
delete obj.latest;
+ +

Определение геттера на уже существующих объектах с помощью defineProperty

+ +

Для добавления геттера к существующему объекту в любое время используйте Object.defineProperty().

+ +
const o = {a: 0};
+
+Object.defineProperty(o, 'b', { get: function() { return this.a + 1; } });
+
+console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)
+
+ +

Использование вычисляемого именованного свойства

+ +
+

Примечание: Вычисляемые свойства являются экспериментальной технологией, частью предложений спецификации ECMAScript 6, и массовой поддержки браузерами пока нет. Код ниже вызовет синтаксическую ошибку в неподдерживаемых средах.

+
+ +
var expr = "foo";
+
+var obj = {
+  get [expr]() { return "bar"; }
+};
+
+console.log(obj.foo); // "bar"
+ +

Умные / самостоятельно перезаписывающиеся/ ленивые геттеры

+ +

Геттеры дают нам возможность определять свойство объекта , но они не вычисляют значение этого свойства до тех пор, пока оно не станет доступно. Геттер откладывает стоимость вычисления значения до тех пор, пока это значение не станет нужно, и если оно никогда не понадобится, то вы никогда не заплатите.

+ +

Дополнительная техника оптимизации заключается в том, чтобы лениться или откладывать вычисление значения свойства и кэшировать его для дальнейшего доступа. Так поступают умные или запоминающие геттеры. Значение вычисляется в первый раз при вызове геттера и затем сохраняется в кэше так, что последующие обращения будут возвращать кэшированные значения без его пересчета. Это полезно в следующих ситуациях:

+ + + +

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

+ +

В следующем примере у объекта есть геттер как собственное свойство. При получении свойства, свойство удаляется из объекта и вновь добавляется, но в этот раз неявно, как свойство с данными. В итоге значение возвращается.

+ +
get notifier() {
+  delete this.notifier;
+  return this.notifier = document.getElementById("bookmarked-notification-anchor");
+},
+ +

Для Firefox смотрите также модуль XPCOMUtils.jsm , который определяет функцию defineLazyGetter().

+ +

get и defineProperty

+ +

Использование ключевого слова get и {{jsxref("Object.defineProperty()")}} дает похожие результаты, но при использовании в {{jsxref("classes")}} между ними есть тонкая разница.

+ +

При использовании get свойство будет определено в прототипе объекта, в то время, как при использовании {{jsxref ("Object.defineProperty ()")}} свойство будет определено в экземпляре, к которому применяется.

+ +
class Example {
+  get hello() {
+    return 'world';
+  }
+}
+
+const obj = new Example();
+console.log(obj.hello);
+// "world"
+console.log(Object.getOwnPropertyDescriptor(obj, 'hello'));
+// undefined
+console.log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), 'hello'));
+// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарии
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}Первоначальное определение.
{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES6')}}Добавлено вычисляемое именное свойство.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}}
+ +

Совместимость с браузерами

+ +

{{Compat("javascript.functions.get")}}

+ +

Смотрите также

+ + diff --git a/files/ru/web/javascript/reference/functions/index.html b/files/ru/web/javascript/reference/functions/index.html new file mode 100644 index 0000000000..0353eb3b84 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/index.html @@ -0,0 +1,483 @@ +--- +title: Функции +slug: Web/JavaScript/Reference/Functions +tags: + - Функции + - Функция +translation_of: Web/JavaScript/Reference/Functions +--- +
{{jsSidebar("Functions")}}
+ +

Сводка

+ +

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

+ +

В JavaScript функции являются объектами первого класса, то есть: они являются объектами и с ними можно взаимодействовать и передавать их точно так же как любой другой объект. Если быть точным, функции — это обьекты Function.

+ +

Больше подробностей и примеров можно найти в руководстве по функциям в JavaScript.

+ +

Описание

+ +

Каждая функция в JavaScript — это объект Function.  О свойствах и методах объектов Function можно прочитать в статье {{jsxref("Function")}}.

+ +

Функции — это не процедуры. Функция всегда возвращает значение, а процедура может возвращать, а может не возвращать.

+ +

Чтобы вернуть значение, отличное от значения по умолчанию, в функции должна быть инструкция return, которая указывает, что именно нужно вернуть. Функция без него вернёт значение по умолчанию. В случае конструктора, вызванного с ключевым словом new, значение по умолчанию — это значение его параметра this. Для остальных функций значением по умолчанию будет undefined.

+ +

Параметры вызова функции называются аргументами функции. Аргументы передаются в функцию по значению. Если функция изменяет значение аргумента, это изменение не отражается на глобальном состоянии или вызывающей функции. Однако ссылки на объекты — это тоже значения, и они отличаются тем, что если функция изменяет свойства объекта по ссылке, это изменение видно снаружи функции, как показано в примере ниже.

+ +
/* Объявляем функцию 'myFunc' */
+function myFunc(theObject) {
+   theObject.brand = "Toyota";
+ }
+
+ /*
+  * Объявляем переменную 'mycar';
+  * создаём и инициализируем новый Object;
+  * приравниваем 'mycar' к ссылке на него
+  */
+ var mycar = {
+   brand: "Honda",
+   model: "Accord",
+   year: 1998
+ };
+
+ /* Выведет 'Honda' */
+ console.log(mycar.brand);
+
+ /* Передаём ссылку на объект в функцию */
+ myFunc(mycar);
+
+ /*
+  * Выведет 'Toyota', так как значение свойства 'brand'
+  * было изменено внутри функции.
+  */
+ console.log(mycar.brand);
+
+ +

Ключевое слово this не ссылается на функцию, которая выполняется в данный момент, поэтому вы должны обращаться к объектами Function по имени, даже внутри тела самой функции.

+ +

Определение функций

+ +

Есть несколько способов определить функцию:

+ +

Объявление функции (инструкция function)

+ +

Специальный синтаксис для объявления функций (более подробно: function statement):

+ +
function name([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
Имя функции.
+
+ +
+
param
+
Имя аргумента, передаваемого в функцию. У функции может быть не более 255 аргументов.
+
+ +
+
statements
+
Инструкции, из которых состоит тело функции.
+
+ +

Функция-выражение (оператор function)

+ +

Функция-выражение похожа на определение функции и имеет такой же синтаксис (более подробно: function operator):

+ +
function [name]([param] [, param] [..., param]) {
+   statements
+}
+
+ +
+
name
+
Имя функции. Может быть не указано, в таком случае функция становится анонимной.
+
+ +
+
param
+
Имя аргумента, передаваемого в функцию. У функции может быть не более 255 аргументов.
+
statements
+
Инструкции, из которых состоит тело функции.
+
+ +

Стрелочная функция-выражение (=>)

+ +
+

Заметка: стрелочные функции являются экспериментальной технологией, частью спецификации ECMAScript 6 и пока что не поддерживаются всеми браузерами.

+
+ +

Стрелочные функции отличаются более кратким синтаксисом и тем, что они лексически связывают значение своего this (подробнее об этом в статье Стрелочные функции):

+ +
([param] [, param]) => {
+   statements
+}
+
+param => expression
+
+ +
+
param
+
Имя параметра. Если параметров нет, вместо них нужно поставить (). Если параметров больше одного, их также нужно заключить в ().
+
statements or expression
+
Если инструкций несколько, их нужно заключить в {}. Для одного выражения фигурных скобок не требуется, а результат этого выражения будет возвращён функцией (то есть функция x => 3 + 8 вернёт 11).
+
+ +

Конструктор Function

+ +
+

Заметка: Использовать конструктор Function не рекомендуется, так как он принимает тело функции в виде строки, а это может помешать оптимизациям, которые выполняют движки JavaScript, а также привести к другим проблемам.

+
+ +

Объекты {{jsxref("Function")}} можно создавать с помощью оператора new (как и любые другие объекты):

+ +
new Function (arg1, arg2, ... argN, functionBody)
+
+ +
+
arg1, arg2, ... argN
+
Ноль или больше имён параметров функции. Имя должно быть строкой, содержащей валидный идентификатор JavaScript. Если параметров несколько, они должны быть разделены запятыми. Например: "x", "theValue", или "a,b".
+
+ +
+
functionBody
+
Инструкции, из которых состоит тело функции.
+
+ +

Конструктор Function можно вызывать и без оператора new, эффект будет тем же.

+ +

Параметры функции

+ +
+

Примечание: Оставшиеся параметры и параметры по умолчанию — это экспериментальная технология, часть спецификации ECMAScript 6, и они пока ещё не получили широкой поддержки среди браузеров.

+
+ +

Параметры по умолчанию

+ +

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

+ +

Оставшиеся параметры

+ +

Синтаксис оставшихся параметров позволяет передать бесконечное число аргументов как массив. Подробности можно найти в статье Оставшиеся параметры.

+ +

Объект arguments

+ +

Внутри функции получить доступ к её аргументам можно через объект arguments.

+ + + +

Определение методов

+ +

Геттеры и сеттеры

+ +

Можно определять геттеры (методы для чтения) и сеттеры (методы для изменения) для любого встроенного или пользовательского объекта, который поддерживает добавление новых свойств. Для этого используется синтаксис литерала объекта.

+ +
+
get
+
Связывает свойство объекта с функцией, которая будет вызвана при обращении к свойству.
+
set
+
Связывает свойство объекта с функцией, которая будет вызвана при попытке изменения свойства.
+
+ +

Синтаксис определения методов

+ +
+

Примечание: Определение методов — это экспериментальная технология, часть спецификации ECMAScript 6, и она пока ещё не получила широкой поддержки среди браузеров.

+
+ +

Начиная с ECMAScript 6, можно определять собственные методы, использу более краткий синтаксис, похожий на геттеры и сеттеры. Более подробно  — в статье Определение методов.

+ +
var obj = {
+  foo() {},
+  bar() {}
+};
+ +

Сравнение конструкторов Function с объявлением функций и функциями-выражениями

+ +

Посмотрите на следующие примеры:

+ +

Функция, определённая через конструктор Function и приравненная к переменной multiply:

+ +
var multiply = new Function("x", "y", "return x * y");
+ +

Объявление функции multiply:

+ +
function multiply(x, y) {
+   return x * y;
+}
+
+ +

Анонимная функция-выражение, приравненная к переменной multiply:

+ +
var multiply = function(x, y) {
+   return x * y;
+};
+
+ +

Функция-выражение с именем func_name, приравненное к переменной multiply:

+ +
var multiply = function func_name(x, y) {
+   return x * y;
+};
+
+ +

Отличия

+ +

Во всех случаях результат примерно одинаков, но есть несколько нюансов:

+ +

Имя функции и переменная, к которой функция приравнена — это не одно и то же. Имя функции нельзя менять, а вот переменной, к которой приравнена функция, можно дать другое значение. В случае функции-выражения с именем, это имя может быть использовано только внутри самой функции. При попытке использовать его снаружи возникнет ошибка (а если ранее была объявлена переменная с таким именем, будет возвращено undefined). Например:

+ +
var y = function x() {};
+alert(x); // выкинет ошибку
+
+ +

Также имя фукнции-выражения проявляется, если сериализовать функцию через метод Function.toString.

+ +

А вот переменная, к которой функция приравнена, ограничена только собственной областью видимости, которая включает ту область, где функция была объявлена.

+ +

Как показано в четвёртом примере, имя функции может отличаться от имени переменной, к которой функция приравнена, эти имена никак не связаны. Объявление функции (function declaration) также создаёт и переменную с именем, аналогичным имени функции. Таким образом:

+ +
    +
  1. Если функция определена с помощью функции-выражения (function expression), её имя доступно только внутри самой функции.
  2. +
  3. Если функция объявлена (function declaration), её имя доступно в той области видимости, где функция была определена.
  4. +
+ +

У функции, определённой с помощью 'new Function', нет имени.  Однако, в JavaScript движке SpiderMonkey, сериализованное представление функции отображается так, как будто оно имеет имя "anonymous". Например, , alert(new Function()) выдаст:

+ +
function anonymous() {
+}
+
+ +

Так как на самом деле у функции нет имени, переменную anonymous нельзя использовать внутри функции. Например, следующий пример выкинет ошибку:

+ +
var foo = new Function("alert(anonymous);");
+foo();
+
+ +

В отличии от функций, определённых через функцию-выражение или конструктор Function, функция, определённая через объявление, может быть использована перед тем, как была определена. Например:

+ +
foo(); // выведет FOO!
+function foo() {
+   alert('FOO!');
+}
+
+ +

Функция, определённая через функцию-выражение, наследует текущую область видимости, то есть создаёт замыкание. А вот функция, созданная с помощью конструктора Function, не наследует ничего, кроме глобальной области видимости (её наследуют вообще все функции).

+ +

Функции, определённые через функцию-выражение и объявление функции парсятся только один раз, в отличиии от функций, созданных с помощью конструктора. То есть строка, которая передаётся в конструктор Function, парсится при каждом вызове конструктора. И хотя функция-выражение каждый раз создаёт замыкание, тело функции при этом не парсится, и получается, что функции-выражение всё равно быстрее, чем "new Function(...)". Поэтому конструктора Function в большинстве случаев стоит избегать, если это возможно.

+ +

Стоит отметить, что функции-выражения и объявления функций внутри функции, созданной при парсинге конструктора Function, парсятся только один раз. Например:

+ +
var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();
+foo(); //  "function() {\n\talert(bar);\n}" Эта часть строки, составляющей тело функции, не парсится во второй раз.
+ +

Объявление функции можно очень легко (и часто случайно) превратить в функцию-выражение. Объявление функции перестаёт быть таковым, если оно:

+ + + +
var x = 0;               // исходный элемент
+if (x == 0) {            // исходный элемент
+   x = 10;               // не исходный элемент
+   function boo() {}     // не исходный элемент
+}
+function foo() {         // исходный элемент
+   var y = 20;           // исходный элемент
+   function bar() {}     // исходный элемент
+   while (y == 10) {     // исходный элемент
+      function blah() {} // не исходный элемент
+      y++;               // не исходный элемент
+   }
+}
+
+ +

Примеры

+ +
// объявление функции
+function foo() {}
+
+// функция-выражение
+(function bar() {})
+
+// функция-выражение
+x = function hello() {}
+
+
+if (x) {
+   // функция-выражение
+   function world() {}
+}
+
+
+// объявление функции
+function a() {
+   // обявление функции
+   function b() {}
+   if (0) {
+      // функция-выражение
+      function c() {}
+   }
+}
+
+ +

Определение функции в зависимости от условия

+ +

Функции могут быть определены в зависимости от условий с помощью инструкции function (разрешённое расширение стандарта ECMA-262 Edition 3) или конструктора Function. Обратите внимание, что подобные инструкции запрещены в ES5 strict. Кроме того, эта возможность по-разному ведёт себя в разных браузерах, поэтому не стоит на неё рассчитывать.

+ +

В коде ниже функция zero никогда не будет определена и не может быть вызвана, потому что 'if (0)' всегда расценивается как false:

+ +
if (0) {
+   function zero() {
+      document.writeln("This is zero.");
+   }
+}
+
+ +

Если изменить условие на  'if (1)', функция zero будет определена.

+ +

Заметьте, что хотя это выглядит как объявление функции, на самом деле, это функция-выражение (или инструкция), так как она вложена внутрь другой инструкции. Изучите разницу между объявлением функции и функцией-выражением.

+ +

Некоторые JavaScript-движки (но не SpiderMonkey), неверно считают любую функцию-выражение с именем за объявление функции. Это приводит к тому, что функция zero будет определена, даже если условие всегда false. Более безопасный способ определить функцию по условию - это сделать её анонимной и приравнять к переменной:

+ +
if (0) {
+   var zero = function() {
+      document.writeln("This is zero.");
+   }
+}
+
+ +

Примеры

+ +

Пример: возврат отформатированного числа

+ +

Эта функция возвращает строку, содержащую число с заданным количеством нулей перед ним:

+ +
function padZeros(num, totalLen) {
+   var numStr = num.toString();             // Инициализировать возвращаемое значение в виде строки
+   var numZeros = totalLen - numStr.length; // Посчитать число нулей в начале
+   for (var i = 1; i <= numZeros; i++) {
+      numStr = "0" + numStr;
+   }
+   return numStr;
+}
+
+ +

Вызовем padZeros:

+ +
var result;
+result = padZeros(42,4); // возвращает "0042"
+result = padZeros(42,2); // возвращает "42"
+result = padZeros(5,4);  // возвращает "0005"
+
+ +

Пример: существует ли функция

+ +

Можно определить, существует ли функция с помощью оператора typeof. В следующем примере проверяется, есть ли у объекта window функция noFunc. Если есть, то она вызывается; если нет, выполняется какое-то другое действие.

+ +
 if ('function' == typeof window.noFunc) {
+   // вызывать noFunc()
+ } else {
+   // сделать что-то другое
+ }
+
+ +

Заметьте, что в проверке условия используется ссылка на noFunc — после имени функции нет скобок, поэтому сама функция не вызывается.

+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
ECMAScript 1st Edition.СтандартИзначальное определение. Релизовано в JavaScript 1.0
{{SpecName('ES5.1', '#sec-13', 'Function Definition')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ES6')}}Новое: стрелочные функции, генераторы, параметры по умолчанию, оставшиеся параметры
+ +

Поддержка браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Начальная поддержка{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Начальная поддержка{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

См. также

+ + diff --git a/files/ru/web/javascript/reference/functions/rest_parameters/index.html b/files/ru/web/javascript/reference/functions/rest_parameters/index.html new file mode 100644 index 0000000000..14d9c1e334 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/rest_parameters/index.html @@ -0,0 +1,209 @@ +--- +title: Оставшиеся параметры (rest parameters) +slug: Web/JavaScript/Reference/Functions/Rest_parameters +tags: + - JavaScript + - Оставшиеся параметры + - Функции +translation_of: Web/JavaScript/Reference/Functions/rest_parameters +--- +
{{jsSidebar("Functions")}} 
+ +

Синтаксис оставшихся параметров функции позволяет представлять неограниченное множество аргументов в виде массива.

+ +

{{EmbedInteractiveExample("pages/js/functions-restparameters.html")}}

+ +

Синтаксис

+ +
function(a, b, ...theArgs) {
+  // ...
+}
+
+ +

Описание

+ +

Если последний именованный аргумент функции имеет префикс ..., он автоматически становится массивом с элементами от 0 до theArgs.length-1 в соответствии с актуальным количеством аргументов, переданных в функцию.

+ +
function myFun(a, b, ...manyMoreArgs) {
+  console.log("a", a);
+  console.log("b", b);
+  console.log("manyMoreArgs", manyMoreArgs);
+}
+
+myFun("один", "два", "три", "четыре", "пять", "шесть");
+
+// Console Output:
+// a, один
+// b, два
+// manyMoreArgs, [три, четыре, пять, шесть]
+
+ +

Отличия оставшихся параметров от объекта arguments

+ +

Существует три основных отличия оставшихся параметров от объекта arguments:

+ + + +

Из аргументов в массив

+ +

Оставшиеся параметры были введены для уменьшения количества шаблонного кода:

+ +
// До появления оставшихся параметров "arguments" конвертировали в обычный массив используя:
+
+function f(a, b) {
+
+  var normalArray = Array.prototype.slice.call(arguments);
+  // -- или --
+  var normalArray = [].slice.call(arguments);
+  // -- или --
+  var normalArray = Array.from(arguments);
+
+  var first = normalArray.shift(); // OK, даёт первый аргумент
+  var first = arguments.shift(); // ERROR (arguments не является обычным массивом)
+
+}
+
+// Теперь мы можем легко получить оставшиеся параметры как обычный массив
+
+function f(...args) {
+  var normalArray = args;
+  var first = normalArray.shift(); // OK, даёт первый аргумент
+}
+ +

Деструктуризация оставшихся параметров

+ +

Оставшиеся парамерты могут быть деструктуризованы (только массивы). Это означает, что их данные могут быть заданы как отдельные значения. Смотрите Деструктурирующее присваивание.

+ +
function f(...[a, b, c]) {
+  return a + b + c;
+}
+
+f(1)          // NaN (b и c равны undefined)
+f(1, 2, 3)    // 6
+f(1, 2, 3, 4) // 6 (четвёртый параметр не деструктурирован)
+ +

Примеры

+ +

В этом примере первый аргумент задан как "a", второй как "b", так что эти аргументы используются как обычно. Однако третий аргумент "manyMoreArgs" будет массивом, который содержит 3-й, 4-й, 5-й, 6-й ... n-й аргументы, которые передаст пользователь.

+ +
function myFun(a, b, ...manyMoreArgs) {
+  console.log("a", a);
+  console.log("b", b);
+  console.log("manyMoreArgs", manyMoreArgs);
+}
+
+myFun("один", "два", "три", "четыре", "пять", "шесть");
+
+// a, один
+// b, два
+// manyMoreArgs, [три, четыре, пять, шесть]
+ +

Ниже... даже если передано одно значение последним аргументом, оно всё равно помещается в массив.

+ +
// использование той же функции, что и в примере выше
+
+myFun("один", "два", "три");
+
+// a, один
+// b, два
+// manyMoreArgs, [три]
+ +

Ниже... третий аргумент не был передан, но "manyMoreArgs" всё ещё массив (хотя и пустой).

+ +
// использование той же функции, что и в примере выше
+
+myFun("один", "два");
+
+// a, один
+// b, два
+// manyMoreArgs, []
+ +

Поскольку theArgs является массивом, количество элементов в нём определяется свойством length:

+ +
function fun1(...theArgs) {
+  console.log(theArgs.length);
+}
+
+fun1();  // 0
+fun1(5); // 1
+fun1(5, 6, 7); // 3
+ +

В следующем примере, оставшиеся параметры используются для сбора всех аргументов после первого в массив. Каждый из них умножается на первый параметр и возвращается массив:

+ +
function multiply(multiplier, ...theArgs) {
+  return theArgs.map(function(element) {
+    return multiplier * element;
+  });
+}
+
+var arr = multiply(2, 1, 2, 3);
+console.log(arr); // [2, 4, 6]
+ +

Методы Array могут быть использованы на оставшихся параметрах, но не на объекте arguments

+ +
function sortRestArgs(...theArgs) {
+  var sortedArgs = theArgs.sort();
+  return sortedArgs;
+}
+
+console.log(sortRestArgs(5, 3, 7, 1)); // 1, 3, 5, 7
+
+function sortArguments() {
+  var sortedArgs = arguments.sort();
+  return sortedArgs; // это никогда не выполнится
+}
+
+
+console.log(sortArguments(5, 3, 7, 1)); // TypeError (arguments.sort is not a function)
+ +

Чтобы использовать методы Array на объекте arguments, нужно преобразовать его в настоящий массив.

+ +
function sortArguments() {
+  var args = Array.from(arguments);
+  var sortedArgs = args.sort();
+  return sortedArgs;
+}
+console.log(sortArguments(5, 3, 7, 1)); // 1, 3, 5, 7
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES6', '#sec-function-definitions', 'Определение функций')}}{{Spec2('ES6')}}Изначальное определение.
{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ESDraft')}}
+ +

Совместимость с браузерами

+ +
{{Compat("javascript.functions.rest_parameters")}}
+ +
+ +

Смотрите также

+ + diff --git a/files/ru/web/javascript/reference/functions/set/index.html b/files/ru/web/javascript/reference/functions/set/index.html new file mode 100644 index 0000000000..8d51101997 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/set/index.html @@ -0,0 +1,134 @@ +--- +title: setter +slug: Web/JavaScript/Reference/Functions/set +translation_of: Web/JavaScript/Reference/Functions/set +--- +
{{jsSidebar("Functions")}}
+ +

Оператор set связывает свойство объекта с функцией, которая будет вызвана при попытке установить это свойство.

+ +

Синтаксис

+ +
{set prop(val) { . . . }}
+{set [expression](val) { . . . }}
+ +

Параметры

+ +
+
prop
+
Имя свойства для привязки к заданной функции.
+
+ +
+
val
+
Псевдоним переменной, которая хранит значение, неудавшегося определения prop.
+
expression
+
Начиная с ECMAScript 6, вы также можете использовать выражения для вычисляемого имя свойства для привязки к данной функции.
+
+ +

Описание

+ +

В JavaScript, сеттер можно использовать для выполнения функции, когда будет попытка изменения указанного свойства. Сеттеры используются чаще всего в сочетании с геттерами для создания одного из видов псевдо-свойства. Невозможно одновременно иметь сеттер для свойства, которое содержит фактическое значение.

+ +

Обратите внимание на следующие моменты при работе с синтаксисом set:

+ +
+ +
+ +

Сеттер может быть удален оператором delete.

+ +

Примеры

+ +

Определение сеттера при инициализации новых объектов

+ +

Это позволит определить псевдо-параметр current объекта o, который задает значение, обновляющее значение log:

+ +
var o = {
+  set current (str) {
+    this.log[this.log.length] = str;
+  },
+  log: []
+}
+
+ +

обратите внимание, что current не определен и любые попытки доступа к нему вернут undefined.

+ +

Удаление сеттера оператором delete

+ +

Если вы хотите удалить сеттер, вы можете просто его удалить:

+ +
delete o.current;
+
+ +

Определение сеттера для существующих объектов используя defineProperty

+ +

Чтобы добавить сеттер на существующий объект в любое время, используйте {{jsxref("Object.defineProperty()")}}.

+ +
var o = { a:0 };
+
+Object.defineProperty(o, "b", { set: function (x) { this.a = x / 2; } });
+
+o.b = 10; // Запускает сеттер, который присваивает 10 / 2 (5) свойству 'a'
+console.log(o.a) // 5
+ +

Использование вычисляемого имени свойства 

+ +
var expr = "foo";
+
+var obj = {
+  baz: "bar",
+  set [expr](v) { this.baz = v; }
+};
+
+console.log(obj.baz); // "bar"
+obj.foo = "baz";      // запускает сеттер
+console.log(obj.baz); // "baz"
+
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}Начальное определение.
{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES6')}}Добавлены вычесляемые имена свойств
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}} 
+ +

Совместимость с браузерами

+ +

{{Compat("javascript.functions.set")}}

+ +

Смотрите также

+ + diff --git "a/files/ru/web/javascript/reference/functions/\320\276\320\277\321\200\320\265\320\264\320\265\320\273\320\270\320\275\320\270\320\265_\320\274\320\265\321\202\320\276\320\264\320\276\320\262/index.html" "b/files/ru/web/javascript/reference/functions/\320\276\320\277\321\200\320\265\320\264\320\265\320\273\320\270\320\275\320\270\320\265_\320\274\320\265\321\202\320\276\320\264\320\276\320\262/index.html" new file mode 100644 index 0000000000..2f50dfe53f --- /dev/null +++ "b/files/ru/web/javascript/reference/functions/\320\276\320\277\321\200\320\265\320\264\320\265\320\273\320\270\320\275\320\270\320\265_\320\274\320\265\321\202\320\276\320\264\320\276\320\262/index.html" @@ -0,0 +1,191 @@ +--- +title: Определение методов +slug: Web/JavaScript/Reference/Functions/Определиние_методов +translation_of: Web/JavaScript/Reference/Functions/Method_definitions +--- +
{{JsSidebar("Functions")}}
+ +

Начиная с ECMAScript 6, существует короткий синтаксис для определения методов в инициализаторе объекта. По сути, это сокращение для функции, которая назначена имени метода.

+ +

Синтаксис

+ +
var obj = {
+  property([parameters]) {},
+  get property() {},
+  set property(value) {},
+  * generator() {}
+};
+
+ +

Описание

+ +

Короткий синтаксис похожий на синтаксис getter'ов и setter'ов представленых в ECMAScript 5.

+ +

Следующий код:

+ +
var obj = {
+  foo: function() {},
+  bar: function() {}
+};
+ +

Вы теперь можете сократить до:

+ +
var obj = {
+  foo() {},
+  bar() {}
+};
+ +

Сокращение методов-генераторов

+ +

Методы-генераторы также могут быть определены используя короткий синтаксис. Обратите внимание, что звездочка (*) в коротком синтаксисе должна быть перед именем свойства генератора. То есть, * g(){} будет работать, а g *(){} не будет.

+ +
// Используя свойство с именем (pre-ES6)
+var obj2 = {
+  g: function*() {
+    var index = 0;
+    while(true)
+      yield index++;
+  }
+};
+
+// Тот же объект используя короткий синтаксис
+var obj2 = {
+  * g() {
+    var index = 0;
+    while(true)
+      yield index++;
+  }
+};
+
+var it = obj2.g();
+console.log(it.next().value); // 0
+console.log(it.next().value); // 1
+ +

Определения методов (ES6) не могут быть конструкторами

+ +

Все определения методов кроме методов-генераторов не могут быть конструкторами и будут выбрасывать {{jsxref("TypeError")}} если вы попытаетесь создать их экземпляр.

+ +
var obj = {
+  method() {},
+};
+new obj.method; // TypeError: obj.method is not a constructor
+
+var obj = {
+  * g() {}
+};
+new obj.g; // Генератор
+
+ +

Примеры

+ +

Простой тестовый пример

+ +
var obj = {
+  a : "foo",
+  b(){ return this.a; }
+};
+console.log(obj.b()); // "foo"
+
+ +

Вычисляемые имена свойств

+ +

Короткий синтаксис также поддерживает вычисляемые имена свойств.

+ +
var bar = {
+  foo0 : function (){return 0;},
+  foo1(){return 1;},
+  ["foo" + 2](){return 2;},
+};
+
+console.log(bar.foo0()); // 0
+console.log(bar.foo1()); // 1
+console.log(bar.foo2()); // 2
+ +

Спецификации

+ + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES6')}}Изначальное определение.
+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Method definition shorthand{{CompatChrome("39")}}{{CompatGeckoDesktop("34")}}{{CompatNo}}{{CompatOpera("26")}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Method definition shorthand{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("34")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

 

+ +

SpiderMonkey-specific notes

+ + + +

Смотрите также

+ + -- cgit v1.2.3-54-g00ecf