From 6cf146d464c904cef12cc4a22e74633fb4801e3c Mon Sep 17 00:00:00 2001 From: Leonid Vinogradov Date: Wed, 31 Jan 2024 01:21:36 +0300 Subject: [PATCH] [ru] improve `Web/JavaScript/Reference/Operators/this` translation (#18073) (#18092) [ru] improve 'Web/JavaScript/Reference/Operators/this' translation (#18073) --- .../reference/operators/this/index.md | 76 ++++++------------- 1 file changed, 23 insertions(+), 53 deletions(-) diff --git a/files/ru/web/javascript/reference/operators/this/index.md b/files/ru/web/javascript/reference/operators/this/index.md index 21ac61e2d1a4fa..5252c0eaf1570a 100644 --- a/files/ru/web/javascript/reference/operators/this/index.md +++ b/files/ru/web/javascript/reference/operators/this/index.md @@ -124,83 +124,53 @@ bar.call(7); // [object Number] bar.call("foo"); // [object String] ``` -### Метод `bind` +### Метод `bind()` -ECMAScript 5 представил {{jsxref("Function.prototype.bind()")}}. Вызов `f.bind(someObject)` создаёт новую функцию с тем же телом и областью действия, что и `f`, но там, где в исходной функции используется `this`, в новой функции оно постоянно будет связано с первым аргументом `bind`, независимо от того, как функция используется. +Вызов [`f.bind(someObject)`](/ru/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) создаёт новую функцию с таким же телом и окружением, что и у `f`, но значение `this` указывает на первый аргумент `bind`, независимо от того, как вызывается функция. ```js function f() { return this.a; } -var g = f.bind({ a: "azerty" }); -console.log(g()); // azerty +const g = f.bind({ a: "qwerty" }); +console.log(g()); // qwerty -var h = g.bind({ a: "yoo" }); // bind only works once! -console.log(h()); // azerty +const h = g.bind({ a: "yoo" }); // bind сработает только один раз! +console.log(h()); // qwerty -var o = { a: 37, f: f, g: g, h: h }; -console.log(o.a, o.f(), o.g(), o.h()); // 37,37, azerty, azerty +const o = { a: 37, f, g, h }; +console.log(o.a, o.f(), o.g(), o.h()); // 37 37 qwerty qwerty ``` -### Стрелочные функции +### `this` в стрелочных функциях -В {{jsxref('Functions/Arrow_functions', 'стрелочных функциях')}}, `this` привязан к окружению, в котором была создана функция. В глобальной области видимости `this` будет указывать на глобальный объект. +Стрелочные функции создают замыкания для значения `this` из окружающего контекста выполнения. В следующем примере мы создаём объект `obj` с методом `getThisGetter`, который возвращает функцию, которая возвращает значение `this`. Возвращаемая функция является стрелочной, поэтому её `this` связано с `this` окружающей функции. Значение `this` внутри `getThisGetter` может быть установлено при вызове, который, в свою очередь, устанавливает возвращаемое значение возвращаемой функции. Мы будем считать, что `getThisGetter` является нестрогой функцией, то есть она находится внутри нестрогого скрипта и не вложена в класс или строгую функцию. ```js -var globalObject = this; -var foo = () => this; -console.log(foo() === globalObject); // true +const obj = { + getThisGetter() { + const getter = () => this; + return getter; + }, +}; ``` -> **Примечание:** Note: если аргумент this передаётся в call, bind или apply при вызове стрелочной функции, он будет проигнорирован. Вы всё ещё можете добавить аргументы к вызову, но первый аргумент (thisArg) должен быть установлен в null. - -Неважно, как стрелочная функция `foo()` будет вызвана, её значение this будет указывать на глобальный объект. `this` будет сохранять своё значение, даже если функция `foo()` будет вызвана как метод объекта (что в обычных функциях связывает `this` с объектом вызова) или с использованием методов `call`, `apply` или `bind`: +Если вызвать `getThisGetter` как метод объекта `obj`, то это свяжет `this` с `obj` внутри его тела. Возвращаемая функция присвоена переменной `fn`. Теперь при вызове `fn` возвращаемое значение `this` по-прежнему задаётся вызовом `getThisGetter`, то есть `obj`. Если бы возвращаемая функция не была стрелочной, то при таких вызовах значение `this` было бы `globalThis`, поскольку `getThisGetter` не является строгой. ```js -// Вызов функции как метода объекта -var obj = { foo: foo }; -console.log(obj.foo() === globalObject); // true - -// Попытка установить this с помощью call -console.log(foo.call(obj) === globalObject); // true - -// Попытка установить this с помощью bind -foo = foo.bind(obj); -console.log(foo() === globalObject); // true +const fn = obj.getThisGetter(); +console.log(fn() === obj); // true ``` -Несмотря ни на что, `this` стрелочной функции `foo()` имеет то же значение, что и при создании функции (глобальный объект в примере выше). То же самое касается стрелочных функций, созданных внутри других функций: их `this` будет привязан к окружению. +Но будьте осторожны при отвязывании метода `obj` без его вызова, потому что `getThisGetter` всё ещё метод, который имеет изменяющееся значение `this`. Вызов `fn2()()` в следующем примере возвращает `globalThis`, потому что он следует за `this` из `fn2()`, который является `globalThis`, поскольку вызывается без привязки к какому-либо объекту. ```js -// Создаём объект obj, содержащий метод bar, который возвращает функцию, -// которая возвращает свой this. Возвращаемая функция создана -// как стрелочная функция, таким образом её this постоянно замкнут -// на this функции, в которой она создана. Значение bar может быть установлено -// в вызове, который, в свою очередь, устанавливает значение возвращаемой функции. -var obj = { - bar: function () { - var x = () => this; - return x; - }, -}; - -// Вызываем bar как метод объекта obj, устанавливая его this на obj -// Присваиваем ссылку возвращаемой функции переменной fn -var fn = obj.bar(); - -// Вызываем fn без установки this, что в обычных функциях указывало бы -// на глобальный объект или undefined в строгом режиме. -console.log(fn() === obj); // true - -// Но будьте осторожны, если вы ссылаетесь на метод obj, не вызывая его -var fn2 = obj.bar; -// Вызов this стрелочной функции изнутри метода bar вернёт теперь window, -// потому что он следует за this из fn2. -console.log(fn2()() == window); // true +const fn2 = obj.getThisGetter; +console.log(fn2()() === globalThis); // true в нестрогом режиме ``` -В примере выше, функция (назовём её анонимной функцией A), присвоенная методу `obj.bar`, возвращает другую функцию (назовём её анонимной функцией B) которая создана как стрелочная функция. В результате, `this функции B при вызове замкнут на` `this,` принадлежащий `obj.bar` (функции A). `this` функции B всегда будет иметь то значение, которое он получил при создании. В примере выше, `this функции B` указывает на `this функции A,которым является` obj, таким образом this будет равен `obj` даже тогда, когда будет вызван методом, который в нормальных условиях устанавливал бы значение this равным `undefined` или глобальному объекту (или любым другим методом, как в предыдущем примере в глобальном контексте выполнения). +Такое поведение очень полезно при определении обратных вызовов. Обычно каждое функциональное выражение создаёт свою собственную привязку `this`, которая перекрывает значение `this` окружающей области видимости. Если вам не важно значение `this`, вы можете определять функции как стрелочные и создавать привязки `this` только там, где это необходимо (например, в методах класса). Смотрите [пример с `setTimeout()`](/ru/docs/Web/JavaScript/Reference/Functions/Arrow_functions#больше_примеров). ### В методе объекта