Movatterモバイル変換


[0]ホーム

URL:


  1. Веб-технологии для разработчиков
  2. JavaScript
  3. Справочник по JavaScript
  4. Выражения и операторы
  5. this

This page was translated from English by the community.Learn more and join the MDN Web Docs community.

View in EnglishAlways switch to English

this

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since ⁨июль 2015 г.⁩.

Поведение ключевого словаthis в JavaScript несколько отличается по сравнению с остальными языками. Имеются также различия при использованииthis встрогом и нестрогом режиме.

В большинстве случаев значениеthis определяется тем, каким образом вызвана функция. Значениеthis не может быть установлено путём присваивания во время исполнения кода и может иметь разное значение при каждом вызове функции. В ES5 представлен методbind(), который используется дляпривязки значения ключевого слова this независимо от того, как вызвана функция. Также в ES2015 представленыстрелочные функции, которые не создают собственные привязки кthis (они сохраняют значениеthis лексического окружения, в котором были созданы).

Интерактивный пример

const test = {  prop: 42,  func: function () {    return this.prop;  },};console.log(test.func());// Expected output: 42

Синтаксис

this

Значение

Свойство контекста выполнения кода (global, function или eval), которое в нестрогом режиме всегда является ссылкой на объект, а в строгом режиме может иметь любое значение.

Global контекст

В глобальном контексте выполнения (за пределами каких-либо функций)this ссылается на глобальный объект вне зависимости от режима (строгий или нестрогий).

js
// В браузерах, объект window также является объектом global:console.log(this === window); // truea = 37;console.log(window.a); // 37this.b = "MDN";console.log(window.b); // "MDN"console.log(b); // "MDN"

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

Function контекст

В пределах функции значениеthis зависит от того, каким образом вызвана функция.

Простой вызов

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

js
function f1() {  return this;}// В браузере:f1() === window; // window - глобальный объект в браузере// В Node:f1() === global; // global - глобальный объект в Node

В строгом режиме, если значениеthis не установлено в контексте выполнения, оно остаётсяundefined, как показано в следующем примере:

js
function f2() {  "use strict"; // см. strict mode  return this;}f2() === undefined; // true

Примечание:Во втором примереthis должно иметь значениеundefined, потому что функцияf2 была вызвана напрямую, а не как метод или свойство объекта (например,window.f2()). Реализация этой особенности не поддерживалась в некоторых браузерах, когда они впервые начали поддерживатьстрогий режим. В результате они некорректно возвращали объектwindow.

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

Пример 1

js
// В качестве первого аргумента методов call или apply может быть передан объект,// на который будет указывать this.var obj = { a: "Custom" };// Это свойство принадлежит глобальному объектуvar a = "Global";function whatsThis() {  return this.a; //значение this зависит от контекста вызова функции}whatsThis(); // 'Global'whatsThis.call(obj); // 'Custom'whatsThis.apply(obj); // 'Custom'

Пример 2

js
function add(c, d) {  return this.a + this.b + c + d;}var o = { a: 1, b: 3 };// Первый параметр - это объект для использования в качестве// 'this', последующие параметры передаются как// аргументы функции calladd.call(o, 5, 7); // 16// Первый параметр - это объект для использования в качестве// 'this', второй - массив, чьи члены используются// в качестве аргументов функции calladd.apply(o, [10, 20]); // 34

Обратите внимание, что в нестрогом режиме, если значение, переданное вcall илиapply какthis, не является объектом, будет сделана попытка преобразовать его в объект с помощью внутренней операцииToObject. Таким образом, если переданное значение является примитивом, таким как7 или'foo', оно будет преобразовано вObject с использованием связанного конструктора, так что примитивное число7 будет преобразовано в объект так, как будто с помощьюnew Number(7), а строка'foo' - как будто с помощьюnew String('foo'), например

js
function bar() {  console.log(Object.prototype.toString.call(this));}bar.call(7); // [object Number]bar.call("foo"); // [object String]

Методbind()

Вызовf.bind(someObject) создаёт новую функцию с таким же телом и окружением, что и уf, но значениеthis указывает на первый аргументbind, независимо от того, как вызывается функция.

js
function f() {  return this.a;}const g = f.bind({ a: "qwerty" });console.log(g()); // qwertyconst h = g.bind({ a: "yoo" }); // bind сработает только один раз!console.log(h()); // qwertyconst o = { a: 37, f, g, h };console.log(o.a, o.f(), o.g(), o.h()); // 37 37 qwerty qwerty

this в стрелочных функциях

Стрелочные функции создают замыкания для значенияthis из окружающего контекста выполнения. В следующем примере мы создаём объектobj с методомgetThisGetter, который возвращает функцию, которая возвращает значениеthis. Возвращаемая функция является стрелочной, поэтому еёthis связано сthis окружающей функции. Значениеthis внутриgetThisGetter может быть установлено при вызове, который, в свою очередь, устанавливает возвращаемое значение возвращаемой функции. Мы будем считать, чтоgetThisGetter является нестрогой функцией, то есть она находится внутри нестрогого скрипта и не вложена в класс или строгую функцию.

js
const obj = {  getThisGetter() {    const getter = () => this;    return getter;  },};

Если вызватьgetThisGetter как метод объектаobj, то это свяжетthis сobj внутри его тела. Возвращаемая функция присвоена переменнойfn. Теперь при вызовеfn возвращаемое значениеthis по-прежнему задаётся вызовомgetThisGetter, то естьobj. Если бы возвращаемая функция не была стрелочной, то при таких вызовах значениеthis было быglobalThis, посколькуgetThisGetter не является строгой.

js
const fn = obj.getThisGetter();console.log(fn() === obj); // true

Но будьте осторожны при отвязывании методаobj без его вызова, потому чтоgetThisGetter всё ещё метод, который имеет изменяющееся значениеthis. Вызовfn2()() в следующем примере возвращаетglobalThis, потому что он следует заthis изfn2(), который являетсяglobalThis, поскольку вызывается без привязки к какому-либо объекту.

js
const fn2 = obj.getThisGetter;console.log(fn2()() === globalThis); // true в нестрогом режиме

Такое поведение очень полезно при определении обратных вызовов. Обычно каждое функциональное выражение создаёт свою собственную привязкуthis, которая перекрывает значениеthis окружающей области видимости. Если вам не важно значениеthis, вы можете определять функции как стрелочные и создавать привязкиthis только там, где это необходимо (например, в методах класса). Смотритепример сsetTimeout().

В методе объекта

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

В следующем примере, когда вызвано свойствоo.f() , внутри функцииthis привязано к объектуo.

js
var o = {  prop: 37,  f: function () {    return this.prop;  },};console.log(o.f()); // logs 37

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

js
var o = { prop: 37 };function independent() {  return this.prop;}o.f = independent;console.log(o.f()); // logs 37

Эти примеры показывают, что имеет значение только то, что функция была вызвана из свойстваf объектаo.

Аналогично, привязываниеthis обуславливается наличием ближайшей ссылки на объект или свойство. В следующем примере, когда мы вызываем функцию, мы обращаемся к ней как к методуg объектаo.b. На этот раз во время выполнения,this, что находится внутри функции, будет ссылаться наo.b. Тот факт, что объект является членом объектаo, не имеет значения; важна только ближайшая ссылка.

js
o.b = { g: independent, prop: 42 };console.log(o.b.g()); // logs 42

this в цепочке object's prototype

Это же представление справедливо и для методов, определённых где-либо в цепочке object's prototype. Если метод находится в цепочке прототипов, тоthis ссылается на объект, на котором был вызван метод, т.е. так, словно метод является методом самого объекта, а не прототипа.

js
var o = {  f: function () {    return this.a + this.b;  },};var p = Object.create(o);p.a = 1;p.b = 4;console.log(p.f()); // 5

В этом примере объект, который присвоен переменнойp, не имеет собственного свойстваf, а наследует это свойство от своего прототипа. Однако, совершенно неважно, что поиск свойства f в конце концов обнаружит его на объектеo. Поскольку поиск начался сp.f, то и свойствоthis внутри функцииf будет ссылаться на объектp. Таким образом, еслиf вызывается как методp, то иthis относится кp. Это полезная особенность прототипного наследования JS.

this с геттерами/сеттерами

Все те же утверждения справедливы, если функция вызывается из геттера или сеттера. Для функции, которая используется как геттер или сеттерthis привязан к объекту, свойство которого необходимо извлечь через геттер/сеттер.

js
function modulus() {  return Math.sqrt(this.re * this.re + this.im * this.im);}var o = {  re: 1,  im: -1,  get phase() {    return Math.atan2(this.im, this.re);  },};Object.defineProperty(o, "modulus", {  get: modulus,  enumerable: true,  configurable: true,});console.log(o.phase, o.modulus); // logs -0.78 1.4142

В конструкторе

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

Примечание: по умолчанию конструктор возвращает объект, на который ссылаетсяthis, но он может вернуть и другой объект (если возвращаемое значение не является объектом, тогда будет возвращён объект сthis).

js
/* * Конструктор работает таким образом: * * function MyConstructor(){ *   // фактический код, составляющий тело функции. *   // создание свойств с |this| по *   // желанию, определяя их значения; например, *   this.fum = "nom"; *   // и т.д. * *   // Если функция возвращает выражение, *   // возвращающее объект, этот объект будет *   // результатом выражения |new|. В обратном случае, *   // результат выражения - объект, *   // в данный момент привязанный к |this| *   // (т.е. наиболее часто встречающийся случай). * } */function C() {  this.a = 37;}var o = new C();console.log(o.a); // logs 37function C2() {  this.a = 37;  return { a: 38 };}o = new C2();console.log(o.a); // logs 38

В последнем примере (C2), из-за того, что конструктор вернул объект, новый объект, к которому было привязаноthis, был просто отброшен. (Это фактически делает выражение "this.a = 37;" "мёртвым" кодом. Он не является буквально нерабочим, так как он выполняется, но он может быть изъят без каких-либо внешних эффектов.)

call иapply

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

js
function add(c, d) {  return this.a + this.b + c + d;}var o = { a: 1, b: 3 };// Первый параметр - это объект, который следует использовать как// 'this', последующие параметры передаются// как аргументы при вызове функцииadd.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16// Первый параметр - объект, который следует использовать как// 'this', второй параметр - массив,// элементы которого используются как аргументы при вызове функцииadd.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

Необходимо отметить, что если методамcall иapply передаётся значение сthis, которое не является при этом объектом, будет предпринята попытка конвертировать значение в объект, используя внутреннюю операциюToObject. Если переданное значение является примитивным типом, например7 или'foo', оно будет преобразовано в объект с использованием родственного конструктора, так примитив7 преобразовывается в объект черезnew Number(7), а строка'foo' в объект черезnew String('foo'), и т.д.

js
function bar() {  console.log(Object.prototype.toString.call(this));}bar.call(7); // [object Number]

Как обработчик событий DOM

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

js
// Когда вызывается как обработчик, связанный элемент становится синимfunction bluify(e) {  // Всегда true  console.log(this === e.currentTarget);  // true, когда currentTarget и target один объект  console.log(this === e.target);  this.style.backgroundColor = "#A5D9F3";}// Получить список каждого элемента в документеvar elements = document.getElementsByTagName("*");// Добавить bluify как обработчика кликов, чтобы при// нажатии на элемент он становился синимfor (var i = 0; i < elements.length; i++) {  elements[i].addEventListener("click", bluify, false);}

В инлайновом обработчике событий

Когда код вызван из инлайнового обработчика,this указывает на DOM-элемент, в котором расположен код события:

js
<button>Показать this</button>

Код выше выведет 'button'. Следует отметить, чтоthis будет указывать на DOM-элемент только во внешних (не вложенных) функциях:

js
<button>  Показать вложенный this</button>

В этом случаеthis вложенной функции не будет установлен, так что будет возвращён global/window объект.

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

Specification
ECMAScript® 2026 Language Specification
# sec-this-keyword

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

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

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp