что такое this в javascript
Ключевое слово 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 ставится на создаваемый объект:
Метод объекта
Если функция запущена как свойство объекта, то в this будет ссылка на этот объект.
При этом совершенно неважно, откуда эта функция взялась. Важно лишь, какой перед func стоит объект.
Пример
Создадим два любых объекта:
Определим никак не связанную с ними функцию say :
Присвоим функцию свойству sayHi для обоих объектов:
И теперь тестовый запуск:
Apply/Call
Вызов через apply удобен тем, что можно самостоятельно сформировать массив аргументов или модифицировать существующий.
Простейший вызов
Шпаргалка
Если кратко срезюмировать все вышесказанное, то получится такая вот шпаргалка:
4 варианта вызова
[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!
Ключевое слово 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» в деталях
Ключевое слово this в javascript работает своеобразно, не так, как в других языках.
В отличие от PHP, Java, C++ и т.п, значение this в javascript не привязывается статически ни к какому объекту, а зависит от контекста вызова.
Разберем все 4 возможных случая.
Режим конструктора
Если функция вызывается через new как конструктор объекта, то this ставится на создаваемый объект:
Метод объекта
Если функция запущена как свойство объекта, то в this будет ссылка на этот объект.
При этом совершенно неважно, откуда эта функция взялась. Важно лишь, какой перед func стоит объект.
Пример
Создадим два любых объекта:
Определим никак не связанную с ними функцию say :
Присвоим функцию свойству sayHi для обоих объектов:
И теперь тестовый запуск:
Apply/Call
Вызов через apply удобен тем, что можно самостоятельно сформировать массив аргументов или модифицировать существующий.
Простейший вызов
Шпаргалка
Если кратко срезюмировать все вышесказанное, то получится такая вот шпаргалка:
4 варианта вызова
[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!