this, self и Me - это ключевые слова, используемые в некоторых компьютерных языках программирования для ссылки на объект, класс или другую сущность, в которой в данный момент выполняется код - это часть. Таким образом, сущность, на которую ссылаются эти ключевые слова, зависит от контекста выполнения (например, у какого объекта вызывается метод). В разных языках программирования эти ключевые слова используются немного по-разному. В языках, где ключевое слово вроде "this" является обязательным, ключевое слово - единственный способ получить доступ к данным и методам, хранящимся в текущем объекте. Где необязательно, они могут устранять неоднозначность переменных и функций с одинаковыми именами.
Во многих объектно-ориентированных языках программирования, this
(также называемый self
или Me
) - это переменная, которая используется в методах экземпляра для ссылки на объект, на котором они работают. Первый объектно-ориентированный язык, SIMULA 67, использовал this
для явной ссылки на локальный объект. C ++ и языки, которые являются производными от него по стилю (например, Java, C#, D и PHP ) также обычно используют this
. Smalltalk и другие, такие как Object Pascal, Perl, Python, Ruby, Rust, Objective-C, DataFlex и Swift, используйте self
. Visual Basic от Microsoft использует Me
.
. Концепция одинакова для всех языков: этот
обычно является неизменяемой ссылкой или указателем, который относится к текущий объект; текущий объект часто является кодом, который действует как «родительский» для свойства , метода, подпрограммы или функции, содержащей ключевое слово this
. После того, как объект правильно сконструирован или создан, этот
всегда является действительной ссылкой. Некоторые языки требуют этого явно; другие используют лексическую область видимости, чтобы использовать ее неявно, чтобы сделать символы внутри своего класса видимыми. Или, в качестве альтернативы, текущий объект, на который ссылается this
, может быть независимым объектом кода, который вызвал функцию или метод, содержащий ключевое слово this
. Такое происходит, например, когда обработчик событий JavaScript, прикрепленный к тегу HTML на веб-странице, вызывает функцию, содержащую ключевое слово this
, хранящееся в глобальном пространстве вне объекта документа. ; в этом контексте this
будет ссылаться на элемент страницы в объекте документа, а не на окружающий объект окна.
В некоторых языках, например C ++ и Java, this
или self
- это ключевое слово, и переменная автоматически существует в методах экземпляра. В других случаях, например Python, Rust и Perl 5, такой ссылкой является первый параметр метода экземпляра. Это нужно указать явно. В Python и Perl параметр не обязательно должен называться this
или self
; программист может произвольно называть его, как и любой другой параметр. Однако по неформальному соглашению первый параметр метода экземпляра в Perl или Python называется self
. Rust требует, чтобы объект self был вызван self
или self
, в зависимости от того, заимствует ли вызываемая функция вызывающий объект или перемещает его, соответственно.
Статические методы в C ++ или Java связаны не с экземплярами, а с классами, и поэтому не могут использовать this
, потому что нет объекта. В других языках, таких как Ruby, Smalltalk, Objective-C или Swift, метод связан с объектом класса, который передается как this
, и они называются методами класса . Для методов класса , Python использует cls
для доступа к объекту класса.
Когда лексическая область видимости используется для вывода этого
, использование this
в коде, хотя и не является незаконным, может вызвать предупреждение звонки программисту по обслуживанию, хотя в этом случае все еще есть законные применения this
, например, ссылка на переменные экземпляра, скрытые локальными переменными с тем же именем, или если метод хочет вернуть ссылку на текущий объект, т.е. этот
, сам.
В некоторых компиляторах (например, GCC ) указатели на методы экземпляра C ++ могут быть напрямую преобразованы в указатель другого типа с явным параметром указателя this
.
Семантика отправки this
, а именно то, что вызовы методов на this
отправляются динамически, известна как открытая рекурсия. и означает, что эти методы могут быть переопределены производными классами или объектами. Напротив, прямая именованная рекурсия или анонимная рекурсия функции использует закрытую рекурсию с ранним связыванием. Например, в следующем коде Perl для факториала токен __SUB__
является ссылкой на текущую функцию:
use feature ": 5.16"; sub {мой $ x = сдвиг; $ x == 0? 1: $ x * __SUB __->($ x - 1); }
Напротив, в C ++ (с использованием явного this
для ясности, хотя и не обязательно) this
привязывается к самому объекту, но если метод класса был объявлен "виртуальным "т.е. полиморфный в основе, он разрешается с помощью динамической отправки (позднее связывание ), так что производные классы могут его переопределить.
unsigned int factorial (unsigned int n) {if (n == 0) возврат 1; иначе верните n * this->factorial (n - 1); }
Этот пример является искусственным, поскольку это прямая рекурсия, поэтому переопределение метода factorial
переопределит эту функцию; более естественными примерами являются случаи, когда метод в производном классе вызывает тот же метод в базовом классе, или в случаях взаимной рекурсии.
Проблема хрупкого базового класса была возложена на открытую рекурсию с предложением, чтобы при вызове методов на этот
по умолчанию использовала закрытую рекурсию (статическая отправка, раннее связывание), а не открытая рекурсия (динамическая отправка, позднее связывание), используя только открытую рекурсию, когда это специально запрашивается; внешние вызовы (без использования this
) будут отправляться динамически, как обычно. На практике это решается в JDK с помощью определенной дисциплины программиста; эта дисциплина была формализована К. Руби и Г. Т. Ливенсом; в основном он состоит из следующих правил:
общедоступных
методов на этот
.защищенный
или частный
метод; если он также должен быть открыт непосредственно для пользователей, тогда метод оболочки public
вызывает внутренний метод.Ранние версии C ++ позволяли изменять указатель this
; таким образом программист мог изменить объект, над которым работает метод. Эта функция была в конечном итоге удалена, и теперь this
в C ++ представляет собой r-значение.
Ранние версии C ++ не включали ссылки, и было высказано предположение, что если бы они были так в C ++ с самого начала, this
был бы ссылкой, а не указателем.
C ++ позволяет объектам уничтожать себя с помощью оператора исходного кода: удалить этот
.
Ключевое слово this
в C # работает так же, как в Java, для ссылочных типов. Однако внутри типов значений C # , этот
имеет совершенно другую семантику, похожую на обычную изменяемую ссылку на переменную, и может даже встречаться в левой части присвоения.
Одно из применений this
в C # - разрешить ссылку на внешнюю переменную поля в методе, который содержит локальную переменную с тем же именем. В такой ситуации, например, инструкция var n = localAndFieldname;
внутри метода присвоит тип и значение локальной переменной localAndFieldname
значению n
, тогда как оператор var n = this.localAndFieldname;
присвоит тип и значение переменной внешнего поля n
.
В D this
в классе, структуре или методе объединения относится к неизменяемая ссылка на экземпляр включающего агрегата. Классы - это ссылочные типы, структуры и объединения - это типы значений. В первой версии D ключевое слово this
используется как указатель на экземпляр объекта, к которому привязан метод, тогда как в D2 он имеет символ неявной ref
аргумент функции.
На языке программирования Дилан, который является объектно-ориентированным языком, который поддерживает мультиметоды и не имеет концепции this
, отправка сообщения объекту все еще сохраняется в синтаксисе. Две формы ниже работают одинаково; различия только в синтаксическом сахаре.
object.method (param1, param2)
и
method (object, param1, param2)
В тексте класса текущий тип - это тип, полученный из текущего класса . В функциях (подпрограммах, командах и запросах) класса можно использовать ключевое слово Current
для ссылки на текущий класс и его функции. Использование ключевого слова Current
является необязательным, поскольку ключевое слово Current
подразумевается простой ссылкой на имя текущего объекта класса открыто. Например: у кого-то может быть функция `foo 'в классе MY_CLASS и ссылаться на нее с помощью:
1 class 2 MY_CLASS 3 4 feature - Access 5 6 foo: INTEGER 7 8 my_function: INTEGER 9 do 10 Результат: = foo 11 end 12 13 end
Строка № 10 (выше) имеет подразумеваемую ссылку на Current
посредством вызова простого `foo '.
Строка № 10 (ниже) имеет явную ссылку на Current
посредством вызова `Current.foo '.
1 класс 2 MY_CLASS 3 4 функция - Доступ 5 6 foo: INTEGER 7 8 my_function: INTEGER 9 do 10 Результат: = Current.foo 11 end 12 13 end
Любой подход приемлем для компилятора, но подразумеваемая версия (например, x: = foo
) является предпочтительной, поскольку она менее подробна.
Как и в других языках, бывают случаи, когда использование ключевого слова Current
является обязательным, например:
1 class 2 MY_CLASS 3 4 feature - Access 5 6 my_command 7 - Создайте MY_OTHER_CLASS с `Current '8 local 9 x: MY_OTHER_CLASS 10 do 11 create x.make_with_something (Current) 12 end 13 14 end
В случае приведенного выше кода вызов в строке # 11 на make_with_something передает текущий класс, явно передав ключевое слово Current
.
. Ключевое слово this
является ключевым словом языка Java, которое представляет текущий экземпляр класса, в котором он появляется. Он используется для доступа к переменным и методам класса.
Поскольку все методы экземпляра виртуальны в Java, this
никогда не может быть пустым.
В JavaScript, который является программированием или язык сценариев, широко используемый в веб-браузерах, это
является важным ключевым словом, хотя его оценка зависит от того, где оно используется.
this
относится к охватывающему объекту, которым в данном случае является закрывающее окно браузера, объект window
.this
, зависит от того, как функция вызывается. Когда такая функция вызывается напрямую (например, f (x)
), this
будет относиться к глобальному пространству, в котором функция определена, и в котором другие глобальные функции и переменные также может существовать (или в строгом режиме это undefined
). Однако, если глобальная функция, содержащая this
, вызывается как часть обработчика событий элемента в объекте документа, this
будет ссылаться на вызывающий элемент HTML.new
(например, var c = new Thing ()
), тогда внутри Thing этот
относится к самому объекту Thing.obj.f (x)
), this
будет ссылаться на объект, в котором содержится функция. Можно даже вручную указать this
при вызове функции, используя методы .call ()
или .apply ()
объекта функции. Например, вызов метода obj.f (x)
можно также записать как obj.f.call (obj, x)
.Чтобы обойти другое значение этого
во вложенных функциях, таких как обработчики событий DOM, распространенной идиомой в JavaScript является сохранение ссылки this
вызывающего объекта в переменной (обычно называемой that
или self
), а затем используйте переменную для ссылки на вызывающий объект во вложенных функциях.
Например:
// В этом примере $ - это ссылка на библиотеку jQuery $ (". Element"). Hover (function () {// Здесь и то, и то указывают на элемент под курсором мыши. var that = this; $ (this).find ('. elements'). each (function () {// Здесь this указывает на повторяемый элемент DOM. // Однако это все еще указывает к элементу под курсором мыши. $ (this).addClass ("highlight");});});
В Lua self
создается как синтаксический сахар, когда функции определяются с использованием оператора :
. При вызове метода с использованием :
индексируемый объект будет неявно передан в качестве первого аргумента вызываемой функции.
Например, следующие две функции эквивалентны:
local obj = {} function obj.foo (arg1, arg2) print (arg1, arg2) - здесь нельзя использовать "self" end function obj : bar (arg) print (self, arg) - «self» - неявный первый аргумент перед arg end - Все функции могут быть вызваны в обоих направлениях, с помощью «.» или с ":" obj: foo ("Foo") - эквивалент obj.foo (obj, "Foo") obj.bar (obj, "Bar") - эквивалент obj: bar ("Bar")
Сам Lua не является объектно-ориентированным, но в сочетании с другой функцией, называемой метатаблицами, использование self
позволяет программистам определять функции способом, напоминающим объектно-ориентированное программирование.
В PowerShell специальная автоматическая переменная $_
содержит текущий объект в объекте конвейера. Эту переменную можно использовать в командах, которые выполняют действие с каждым объектом или с выбранными объектами в конвейере.
«один», «два», «три» | % {write $ _}
Также, начиная с PowerShell 5.0, который добавляет формальный синтаксис для определения классов и других определяемых пользователем типов, $ this
переменная описывает текущий экземпляр объекта.
В Python нет ключевого слова для this
. Когда функция-член вызывается для объекта, она вызывает функцию-член с тем же именем для объекта класса объекта, при этом объект автоматически связывается с первым аргументом функции. Таким образом, обязательный первый параметр методов экземпляра служит this
; этот параметр обычно называется self
, но может называться как угодно.
В методах класса (созданных с помощью декоратора classmethod
) первый аргумент относится к самому объекту класса и обычно называется cls
; они в основном используются для наследуемых конструкторов, где использование класса в качестве параметра позволяет создать подкласс конструктора. В статических методах (созданных с помощью декоратора staticmethod
) не существует специального первого аргумента.
В Rust типы объявляются отдельно от связанных с ними функций. Функции, разработанные как аналог методов экземпляра в более традиционно объектно-ориентированных языках, должны явно принимать self
в качестве своего первого параметра. Эти функции затем могут быть вызваны с использованием синтаксического сахара instance.method ()
. Например:
struct Foo {bar: i32,} impl Foo {fn new () ->Foo {Foo {bar: 0,}} fn refer (self) {println! ("{}", Self.bar); } fn mutate (mut self, baz: i32) {self.bar = baz; } fn потреблять (сам) {self.refer (); }}
Это определяет тип, Foo
, с четырьмя связанными функциями. Первая, Foo :: new ()
, не является функцией экземпляра и должна быть указана с префиксом типа. Остальные три все принимают параметр self
различными способами и могут быть вызваны в экземпляре Foo
с использованием синтаксического сахара с точечной нотацией, что эквивалентно вызову типа - квалифицированное имя функции с явным первым параметром self
.
let foo = Foo :: new (); // должна вызываться как функция указанного типа foo.refer (); // выводит "0". Foo :: refer () имеет доступ только для чтения к экземпляру foo foo.mutate (5); // изменяет foo на место, разрешенное спецификацией mut foo.consume (); // выводит "5" и уничтожает foo, поскольку Foo :: consumer () получает полное право собственности на self // эквивалентно foo.refer () Foo :: refer (foo); // ошибка компиляции: foo выходит за рамки
Язык Self назван в честь этого использования «self».
Self
строго используется в методах класса. Другой способ сослаться на Self
- использовать ::
.