Что возвращает this c
Урок №121. Скрытый указатель *this
Обновл. 13 Сен 2021 |
Один из частых вопросов, которые новички задают по поводу классов: «При вызове метода класса, как C++ отслеживает то, какой объект его вызвал?». Ответ заключается в том, что C++ для этих целей использует скрытый указатель *this!
Скрытый указатель *this
Ниже приведен простой класс, который содержит целочисленное значение и имеет конструктор и функции доступа. Обратите внимание, деструктор здесь не нужен, так как язык C++ может очистить память после переменной-члена самостоятельно:
Результат выполнения программы:
Возьмем, к примеру, следующую строку:
Хотя на первый взгляд кажется, что у нас здесь только один аргумент, но на самом деле у нас их два! Во время компиляции строка another.setNumber(4); конвертируется компилятором в следующее:
Теперь это всего лишь стандартный вызов функции, а объект another (который ранее был отдельным объектом и находился перед точкой) теперь передается по адресу в качестве аргумента функции.
Но это только половина дела. Поскольку в вызове функции теперь есть два аргумента, то и метод нужно изменить соответствующим образом (чтобы он принимал два аргумента). Следовательно, следующий метод:
Конвертируется компилятором в:
При компиляции обычного метода, компилятор неявно добавляет к нему параметр *this. Указатель *this — это скрытый константный указатель, содержащий адрес объекта, который вызывает метод класса.
Соединяем всё вместе:
Хорошей новостью является то, что это всё происходит скрыто от нас (программистов), и не имеет значения, помните ли вы, как это работает или нет. Всё, что вам нужно запомнить — все обычные методы класса имеют указатель *this, который указывает на объект, связанный с вызовом метода класса.
Указатель *this всегда указывает на текущий объект
Начинающие программисты иногда путают, сколько указателей *this существует. Каждый метод имеет в качестве параметра указатель *this, который указывает на адрес объекта, с которым в данный момент выполняется операция, например:
Ключевое слово this в JavaScript для начинающих
Что такое this?
Причина, по которой this вызывает столько путаницы у новичков, заключается в том, что контекст this меняется в зависимости от его использования.
Ситуации, когда this указывает на объект window
Если вы попытаетесь обратиться к ключевому слову this в глобальной области видимости, оно будет привязано к глобальному контексту, то есть — к объекту window в браузере.
Попробуйте выполнить этот код, например, в консоли браузера:
Использование this внутри объекта
This и вложенные объекты
Применение this во вложенных объектах может создать некоторую путаницу. В подобных ситуациях стоит помнить о том, что ключевое слово this относиться к тому объекту, в методе которого оно используется. Рассмотрим пример.
Особенности стрелочных функций
Стрелочные функции ведут себя не так, как обычные функции. Вспомните: при обращении к this в методе объекта, этому ключевому слову соответствует объект, которому принадлежит метод. Однако это не относится к стрелочным функциям. Вместо этого, this в таких функциях относится к глобальному контексту (к объекту window ). Рассмотрим следующий код, который можно запустить в консоли браузера.
Прислушаемся к MDN и не будем использовать стрелочные функции в качестве методов объектов.
Использование this в обычных функциях
Обращение к this из функции, которая была объявлена за пределами объекта, а потом назначена в качестве его метода
Ключевое слово new и this
Вот как можно работать со стандартными конструкторами JavaScript.
Вот ещё один пример использования функций-конструкторов.
О важности ключевого слова new
При вызове функции-конструктора с использованием ключевого слова new ключевое слово this указывает на новый объект, который, после некоторой работы над ним, будет возвращён из этой функции. Ключевое слово this в данной ситуации весьма важно. Почему? Всё дело в том, что с его помощью можно, используя единственную функцию-конструктор, создавать множество однотипных объектов.
Итоги
Уважаемые читатели! Возникали ли у вас сложности с пониманием ключевого слова this в JavaScript?
Что возвращает this c
Поведение ключевого слова 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 в языке С++
Просто для общего развития хочу понять на что способен this.
Использование оператора Case в разветвляющемся вычислительном процессе в языке Pascal
Преобразовать целое число N в зависимости от величины остатка от его деления на 17 следующим.
Нестатические методы не могут существовать сами по себе, они должны быть привязаны к объекту, то есть в момент вызова должен быть указан объект, к которому они относятся.
Добавлено через 56 секунд
Например, квалификатор const после описания метода как раз относится к этому неявному *this. То есть накладывает ограничение на изменение *this.
Вы опять за старое. Если я не понимаю, что такое явное, не явное и параметр(где,что) как я могу понять определение на этих не понятных для меня словосочетаниях?
Лучше время потратить на код, который покажет разные результаты при использовании this и не использующих this.
Лучше это в коде показать разницу. Чем на непонятных терминах изъяснятся. Поймите новичков.
Лучше потратьте время на код, где будет использовано this и чтобы код показал разницу или эффект этого this. Код должен выводить на экран результат работы this.
Как минимум я понял.
Добавлено через 1 минуту
Как вы иначе вернёте «текущий объект» из метода, который возвращает объект данного типа?
Пример такого метода, оператор копирующего присваивания, приведён выше.
Решение
Добавлено через 8 минут
Смотреть в сторону Two-phase name lookup
Поведение метода void setName1(const std::string& n)
Добавлено через 1 минуту
чем функци-члены классов отличаются от обычных «свободных» функций?
тем, что функции-члены (их ещё любят называть методами) классов,
вызываются для какого то объекта.
и могут менять его состояние.
но как функция-член класса узнает для какого объекта она была вызвана?
для этого компилятор генерирует код, передавая методам скрытый указатель this
который собственно и указывает на этот объект.
ключевое слово 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.