javascript зачем нужен this

Javascript зачем нужен this

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

Исходный код этого интерактивного примера хранится в репозитории на GitHub. Если вы хотите поучаствовать в создании этого интерактивного примера, склонируйте репозиторий про адресу https://github.com/mdn/interactive-examples и присылайте пулреквест.

Синтаксис

Значение

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

Global контекст

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

Function контекст

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

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

Пример 1

Пример 2

Метод bind

Стрелочные функции

Note: если аргумент this передаётся в call, bind или apply при вызове стрелочной функции, он будет проигнорирован. Вы всё ещё можете добавить аргументы к вызову, но первый аргумент (thisArg) должен быть установлен в null.

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

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

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

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

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

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

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

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

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

call и apply

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

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

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

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

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

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

Источник

Методы объекта, «this»

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

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

Такие действия в JavaScript представлены свойствами-функциями объекта.

Примеры методов

Для начала давайте научим нашего пользователя user здороваться:

Здесь мы просто использовали Function Expression (функциональное выражение), чтобы создать функцию для приветствия, и присвоили её свойству user.sayHi нашего объекта.

Затем мы вызвали её. Теперь пользователь может говорить!

Функцию, которая является свойством объекта, называют методом этого объекта.

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

Когда мы пишем наш код, используя объекты для представления сущностей реального мира, – это называется объектно-ориентированное программирование или сокращённо: «ООП».

ООП является большой предметной областью и интересной наукой само по себе. Как выбрать правильные сущности? Как организовать взаимодействие между ними? Это – создание архитектуры, и есть хорошие книги по этой теме, такие как «Приёмы объектно-ориентированного проектирования. Паттерны проектирования» авторов Эрих Гамма, Ричард Хелм, Ральф Джонсон, Джон Влиссидес или «Объектно-ориентированный анализ и проектирование с примерами приложений» Гради Буча, а также ещё множество других книг.

Сокращённая запись метода

Существует более короткий синтаксис для методов в литерале объекта:

Нужно отметить, что эти две записи не полностью эквивалентны. Есть тонкие различия, связанные с наследованием объектов (что будет рассмотрено позже), но на данном этапе изучения это неважно. В большинстве случаев сокращённый синтаксис предпочтителен.

Ключевое слово «this» в методах

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

Значение this – это объект «перед точкой», который использовался для вызова метода.

Здесь во время выполнения кода user.sayHi() значением this будет являться user (ссылка на объект user ).

«this» не является фиксированным

В JavaScript ключевое слово «this» ведёт себя иначе, чем в большинстве других языков программирования. Оно может использоваться в любой функции.

В этом коде нет синтаксической ошибки:

Значение this вычисляется во время выполнения кода и зависит от контекста.

Например, здесь одна и та же функция назначена двум разным объектам и имеет различное значение «this» при вызовах:

Мы даже можем вызвать функцию вовсе без использования объекта:

Если вы до этого изучали другие языки программирования, тогда вы, скорее всего, привыкли к идее «фиксированного this » – когда методы, определённые внутри объекта, всегда сохраняют в качестве значения this ссылку на свой объект (в котором был определён метод).

В JavaScript this является «свободным», его значение вычисляется в момент вызова метода и не зависит от того, где этот метод был объявлен, а зависит от того, какой объект вызывает метод (какой объект стоит «перед точкой»).

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

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

Внутренняя реализация: Ссылочный тип

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

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

Вы можете видеть, что при вызове будет ошибка, потому что значением «this» внутри функции становится undefined (полагаем, что у нас строгий режим).

Так работает (доступ к методу объекта через точку):

Так уже не работает (вызываемый метод вычисляется):

Почему? Если мы хотим понять, почему так происходит, давайте разберёмся (заглянем под капот), как работает вызов методов ( obj.method() ).

Присмотревшись поближе, в выражении obj.method() можно заметить две операции:

Итак, каким же образом информация о this передаётся из первой части во вторую?

Этот ссылочный тип (Reference Type) является внутренним типом. Мы не можем явно использовать его, но он используется внутри языка.

Результатом доступа к свойству user.hi является не функция, а значение ссылочного типа. Для user.hi в строгом режиме оно будет таким:

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

У стрелочных функций нет «this»

Например, здесь arrow() использует значение this из внешнего метода user.sayHi() :

Итого

Значение this определяется во время исполнения кода.

Источник

О ключевом слове «this» языка JavaScript: особенности использования с пояснениями

Авторизуйтесь

О ключевом слове «this» языка JavaScript: особенности использования с пояснениями

Тайна this

Долгое время ключевое слово this оставалось для меня загадкой. Это мощный инструмент, но разобраться в нём нелегко.

С точки зрения Java, PHP или любого другого обычного языка this расценивается как экземпляр текущего объекта в методе класса, не больше и не меньше. Чаще всего его нельзя использовать вне метода, и этот подход не вызывает непонимания.

В JavaScript this — это текущий контекст исполнения функции. Поскольку функцию можно вызвать четырьмя способами:

и каждый из них определяет свой контекст, поведение this слегка не соответствует ожиданиям начинающих разработчиков. Кроме того, strict mode также влияет на контекст исполнения.

12–14 ноября, Онлайн, Беcплатно

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

Прежде чем мы начнём, давайте познакомимся с несколькими терминами:

Содержание:

Вызов функции

Простой пример вызова функции:

this при вызове функции

this — это глобальный объект при вызове функции

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

Когда this используется вне области видимости какой-либо функции (самая внешняя область видимости: контекст глобального исполнения), он также относится к глобальному объекту:

this при вызове функции в strict mode

this принимает значение undefined при вызове функции в strict mode

Пример функции, запущенной в strict mode:

Strict mode активен не только в текущей области видимости, но и во всех вложенных:

Один файл JavaScript может содержать как «строгие», так и «нестрогие» функции. Поэтому возможно иметь в одном скрипте разные контексты исполнения для одного типа вызова:

Ловушка: this во внутренней функции

Обычной ошибкой при работе с вызовом функции является уверенность в том, что this во внутренней функции такой же, как и во внешней.

Вообще-то контекст внутренней функции зависит только от вызова, а не от контекста внешней функции.

Следующий пример вычисляет сумму двух чисел:

Вызов метода

Метод — это функция, хранящаяся в объекте. Пример:

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

this при вызове метода

this — это объект, которому принадлежит метод

При вызове метода, принадлежащего объекту, this становится этим объектом.

Давайте создадим объект, метод которого увеличивает число на 1:

Объект JavaScript наследует метод своего прототипа. Когда вызывается метод, унаследованный от объекта, контекстом всё равно является сам объект:

В синтаксисе ECMAScript 6 class контекст вызова метода — тоже сам объект:

Ловушка: отделение метода от его объекта

Метод объекта можно переместить в отдельную переменную. При вызове метода с использованием этой переменной вы можете подумать, что this — это объект, в котором определён метод.

Вызов конструктора

Начиная с ECMAScript 6, JavaScript позволяет определять конструкторы ключевым словом class :

Вызов конструктора создаёт новый пустой объект, наследующий свойства от прототипа конструктора. Ролью функции-конструктора является инициализация объекта. Как вы уже знаете, контекст этого типа вызова называется экземпляром. Это — тема следующей главы.

this в вызове конструктора

this — это только что созданный объект

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

Давайте проверим контекст в следующем примере:

Ловушка: как не забыть про new

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

При исполнении new RegExp(‘\\w+’) и RegExp(‘\\w+’) JavaScript создаёт эквивалентные объекты регулярных выражений.

Следующий пример иллюстрирует проблему:

Тем не менее, this — это объект window при вызове функции, и Vehicle(‘Car’, 4) задаёт свойства объекта window — упс, что-то пошло не так. Новый объект не создан.

Непрямой вызов

Следующий пример демонстрирует непрямой вызов:

this при непрямом вызове

Ещё одним примером использования является создание иерархии классов в ES5 для вызова родительского конструктора:

Runner.call(this, name) в Rabbit создаёт непрямой вызов родительской функции для инициализации объекта.

Связанная функция

Следующий код создаёт связанную функцию и вызывает её:

this в связанной функции

Давайте посмотрим, как настроить this связанной функции:

Только вызов связанной функции как конструктора может изменить контекст, но это не рекомендуется (используйте нормальные функции).

В следующем примере сперва объявляется связанная функция, а затем производится попытка изменить контекст:

Стрелочная функция

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

Её можно использовать следующим образом:

this в стрелочной функции

this — это контекст, в котором определена стрелочная функция

Стрелочная функция не создаёт свой контекст исполнения, а заимствует this из внешней функции, в которой она определена.

Следующий пример показывает прозрачность контекста:

Если стрелочная функция определена вне всех функций, её контекст — глобальный объект:

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

Ловушка: определение метода стрелочной функцией

Вы можете захотеть использовать стрелочную функцию для объявления метода. Справедливо: их объявления гораздо короче по сравнению с обычным выражением: (param) => <. >вместо function(param) <..>.

В этом примере демонстрируется определение метода format() класса Period с использованием стрелочной функции:

Функциональное выражение решает проблему, поскольку обычная функция изменяет свой контекст в зависимости от вызова:

Заключение

а спрашивайте:

А в случае со стрелочной функцией спросите:

Каков this там, где объявлена стрелочная функция?

Такой подход к this убережет вас от лишней головной боли.

Источник

Ключевое слово this в javascript — учимся определять контекст на практике

По просьбам некоторых читателей решил написать топик про контекст в javascript. Новички javascript часто не понимают значение ключевого слова this в javascript. Данный топик будет интересен не только новичкам, а также тем, кто просто хочет освежить данный аспект в памяти. Посмотрите пример ниже. Если вы затрудняетесь ответить на вопрос «что будет выведено в логе» хотя бы в одном из пунктов или хотите просто посмотреть ответы — добро пожаловать под кат.

1. Теория

В отличие от многих других языков программирования ключевое слово this в javascript не привязывается к объекту, а зависит от контекста вызова. Для упрощения понимания будем рассматривать примеры применительно к браузеру, где глобальным объектом является window.

1.1. Простой вызов функции

В данном случае this внутри функции f равен глобальному объекту (например, в браузере это window, в Node.js — global).

Самовызывающиеся функции (self-invoking) работают по точно такому же принципу.

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

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

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

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

1.4. Методы apply, call

Методы apply и call позволяют задать контекст для выполняемой функции. Разница между apply и call — только в способе передачи параметров в функцию. Первый параметр обеих функций определяет контекст выполнения функции (то, чему будет равен this).

2. Разбираем задачу

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

Источник

Форум

Справочник

Ключевое слово «this» в деталях

Ключевое слово this в javascript работает своеобразно, не так, как в других языках.

В отличие от PHP, Java, C++ и т.п, значение this в javascript не привязывается статически ни к какому объекту, а зависит от контекста вызова.

Разберем все 4 возможных случая.

Режим конструктора

Если функция вызывается через new как конструктор объекта, то this ставится на создаваемый объект:

javascript зачем нужен this. Смотреть фото javascript зачем нужен this. Смотреть картинку javascript зачем нужен this. Картинка про javascript зачем нужен this. Фото javascript зачем нужен this

Метод объекта

Если функция запущена как свойство объекта, то в this будет ссылка на этот объект.

При этом совершенно неважно, откуда эта функция взялась. Важно лишь, какой перед func стоит объект.

Пример

Создадим два любых объекта:

Определим никак не связанную с ними функцию say :

Присвоим функцию свойству sayHi для обоих объектов:

И теперь тестовый запуск:

Apply/Call

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

Простейший вызов

Шпаргалка

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

4 варианта вызова

javascript зачем нужен this. Смотреть фото javascript зачем нужен this. Смотреть картинку javascript зачем нужен this. Картинка про javascript зачем нужен this. Фото javascript зачем нужен this

[a href=»#» onclick=»myFunction(this)»]

при таком вызове this будет указывать на [a] я так понимаю

[a href=»#» onclick=»myFunction(this)»]
при таком вызове this будет указывать на [a] я так понимаю

А если [a href=»javascript:myFunction(this);»]? У меня почему-то при таком вызове this ведет «на Марс».

Я тоже сталкивался с такой проблемой, href=»javascript: func(this);» в this был window

Да, но вот переменная this внутри myFunction буде указывать на window

Допустим у нас есть такой набор функций

тогда как сделать чтобы внутри вызова

this указывало на объект полученный через $(‘id’)?

Этот вопрос очень подробно разобран в статье про замыкания. Там в конце разобран пример, очень похожий на ваш.

Спасибо.
Собственно проблема была только в ИЕ, изменил код следующим образом:

только теперь непонятно как реализовать detachEvent, может существует какойто другой способ?

Данный код подтверждает, что this ведет как раз себя не так в PHP и С++.
«I am A!» и не выведется никогда, поскольку вы не запрашивали вывод сообщения с переменной из а

Разберемся с вашими тестами:

Будет выведено «I am A->B->C. «, поскольку this ссылается на a.b.c.who

Вне зависимости от того, где описана ваша функция в этой случае this будет ссылаться на a.b.who

Так, что все верно. А чтобы вывелось «I am A!», необходимо
добавить строку:

Подскажите плиз, как избавиться от переполнения стэка. Я головой понимаю, что что-то глупое делаю, но найти второй день не могу.
Аналог кода:

Прошу прощения, уже нашел, здесь же, на сайте, так что все равно еще раз спасибо)) (сделал через
вар селф = зис;
сетТаймаут(функция () <селф.б()>, 100)
)

к ней обращщается объект TABLE:

Но this все равно определяется,как window. Почему?

Это частая ошибка. this правильный в самом обработчике:

Если ты вызываешь функцию из него, то у нее будет свой this. Можно явно указать нужный this через call :

[quote]При таком вызове this ставится равным глобальному объекту window.[/quote]
Есть тут, imho, две ошибки, причем первая по всей статье прослеживается.

Про глобальный объект добавил упоминание и поправил фразу про указатель.

Респект автору, достойная инфа по теме.

По-моему, этот код из примера надо исправить:

Параметр phrase лишний. Так же?
Ерунда, но для читабельности полезным будет.

Подскажите, пожалуйста, не могу понять, как мне получить в функции ссылку на объект?

Подскажите, пожалуйста, не могу понять, как мне получить в функции ссылку на объект?

и ссылаться в функции на this.self.

Подскажите пожалуйста, почему не работает такой код:

function closer() <
this.showsec= 15;
>

closer.prototype= <
progress: function() <
alert(this);
>,

start: function() <
alert(this);
setTimeout.call(this, this.progress, 1000 );
>
>

var cl= new closer();
cl.showsec= 20;
cl.start();

Правильно будет не так

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

Извините, очепятался во втором варианте:

Возможно я ошибаюсь, но на мой взгляд должно быть так:

P.S. Я пробовал похожий код на ‘setInterval’ и с this пример не работал.

Почитал статью про замыкания, переписал так:

но вреравно интересно, почему не работает

хотя такой вариант работает

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

Здравствуйте!
А, если можно, объясните, пожалуйста, в чём разница между конструкцией из примера про «Васю и Диму»:

подскажите пожалуйста как в этих случаях работает this

извините пожалуйста, подскажите код, удаляющий строку, например в таблице на которую нажали?

если использовать jquery

а вот так удалится что угодно

Помогите пожалуйста разобраться

сам разобрался, может кому еще поможет

say = function() <
alert(«Привет, я «+this.name)
>

vasya = <
name: «Василий»
>
dima = <
name: «Дмитрий»
>

vasya.sayHi = say
dima.sayHi = say

не работает, подскажите плз где у меня ошибка

Работаю с JavaScript уже более трёх лет. Хотелось бы поделиться опытом по этой теме. Может, это уже известно вам, но не отнеситесь критически, потому что это полезно для новичков.

P.S. Извиняюсь за поехавшие в коде табы.

Как говорится, прочитал всё от корки до корки. Касательно только JavaScript на этом сайте.
Замечательный сайт в плане общего ознакомления с тем, что такое JavaScript. И всё же скажу, что об ООП здесь сказано на очень низком уровне. Статьи про объекты и ООП здесь читателям позволят научиться лишь не блуждать в коде, который они читают. Сами они навряд ли смогут после прочтения этих статей что-либо сделать.
И всё же сайт на столько же хорош в своей тематики, на сколько в своей htmlbook.ru.

Для тех же, кто желает продолжить изучение и научиться хорошо(профессионально) программировать на JavaScript, хотел бы посоветовать книгу Джона Рейсига(главного разработчика библиотеки jquery) под названием «Профессиональные приёмы программирования». Хорошая книга, которая позволит вникнуть в суть JavaScript, познакомит с технологией Ajax и, что немаловажно, научит мыслить в режиме ООП.
В данной книге напрочь отсутствуют введение в JavaScript и прочие обучающие детали. Поэтому эта книга очень хороша для того, чтобы продолжить изучать JavaScript сразу после прочтения статей на этом сайте. =)
P.S. отсутствие введения и прочей шелухи для новичков сократило объём книги с стандартных 700-1000 страниц для книг схожей тематики, до 250.

Прошу прощения, всё работает! Комент удалить бы.

Подскажите пожалуйста в моём случае

Вопрос: и как это понимать?

this должна быть undefined, т.к. f2 была вызвана без предоставления контекста (например window.f2() )

Можно еще дописать, на всякий случай, что в такой-вот конструкции:

this будет obj2, и, как я понял, это единственная ситуация, где следует вызывать функцию через call/apply, а не напрямую.
(объясняю, если нужно вызвать функцию, которая находится в каком-то объекте, но как this передать ей не этот объект, а другой. В принципе, нужный объект можно и параметром передать, но иногда такой вариант удобнее, в особенности если у Вас смоделированы «абстрактные классы», как тот же Math)

Но это зацикливание ссылок, браузер не ругается.. но это не гуд.

Но это зацикливание ссылок, браузер не ругается.. но это не гуд.

Вы бы разделили все: 1.атрибуты и теги HTML и CSS, 2.DOM, 3.атрибуты/свойства, методы, события и объектов в коде JavaScript.

Например, событие onreadystatechange или свойства complete || readyState, для img, вообще нигде нет.

Привели бы общий список событий, свойств, методов, доступных в кодe JavaScript.

Ну, в общем вам еще писать и писать. ))

как правильно описать картинку с помощью объектов которые есть?

Вопрос к гуру js.
Имеется код (это всего лишь удобный пример, но суть вопроса остается)

Нужно обратиться к свойству Country.name изнутри объекта capital. Есть ли какие более-менее элегантные способы это сделать? Кроме переделывания всего кода с созданием двух классов Country, Capital, и специального поля country внутри Capital (для хранения к какой стране принадлежит) и с последующим присваиванием в виде

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

Можно попробовать так

Очевидно, на этом сайте не тусят специалисты в js)) Одни кодеры, что и умеющие так только добавить в html событие onclick)

Помогите разобраться, вообщем есть такой код:

function Boxs(width,height,bgColor) <
this.width = width;
this.height = height;
this.bgColor = bgColor;
>

var box = new Boxs(250,250,’green’);
var box2 = new Boxs(200,200,’yellow’);

//Создание коробки
Boxs.prototype.createBox = function(width,height,bgColor) <
$(‘#idDiv’).append(‘

Когда я вызываю метод «createBox()» оно создает блок с заданными параметрами в объекте «box», но если я после этого вызову тот же метод но уже для другого объекта который имеет другие параметры, то «this» будет брать параметры из «box2», и сделает 2 блока со свойствам «box2».

Как сделать так что бы у меня вышли 2 блока с разными параметрами (только осваиваю js).

В строке:
Boxs.prototype.createBox = function(width,height,bgColor)<

(width,height,bgColor) были пусты вначале, это я экспериментировал хД.

Couldn’t be written any better. Reading this post reminds me of my old room mate! He always kept talking about this. I will forward this article to him. Pretty sure he will have a good read. Thanks for sharing!

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *