Давным-давно, в далекой-далекой галактике...
Раньше я зарабатывал на жизнь разливом напитков из-за барной стойки. Мои коллеги и я предполагали, что мохито изобрел какой-то бедный ублюдок, поклявшийся отомстить бармену, который пригласил его мать на вкусный ужин из морепродуктов и больше никогда ей не звонил (да, вы правы. Справочник ведущего!И спросите у любого бармена, они согласятся). В любом случае, после того, как на прошлой неделе вы разобрались с ловушками ключевого слова this, можно с уверенностью предположить, что бармен также был разработчиком Javascript!
О чем «это» (в Javascript)?
Перво-наперво! Этобудет служить ссылкой на ключевое слово this для остальной части публикации.
Это одно из самых неуловимых понятий в Javascript. Это вдвойне важно, если вы только начинаете изучать язык. Вдобавок ко всему, постарайтесь найти эту чертову вещь в Google. Все, что вы найдете, это благонамеренные, двусмысленные описания, прежде чем автор просто начнет приводить примеры. Итак, по традиции постов в блоге с ключевым словом «это», вот МОИ два цента:
"это" (существительное)
Ключевое слово, зарезервированное для привязки и использования в качестве ссылки на объект во время вызова/вызова метода или конструктора. Часто ему предшествуют умоляющие фразы, например: «Я надеюсь, что это сработает… Пожалуйста, пожалуйста, работайте… Если это не сработает, я… и т. д.».
Так почему же вся эта путаница, когда дело доходит до этого?
По умолчанию this привязан к глобальному объекту. ЭтоНЕ просто ссылка на функцию, в которой оно появляется. Эта мысль является распространенной ошибкой для многих, поэтому не будьте жертвой ! На самом деле, если бы мы вызывали функцию с this без передачи контекста объекта, привязка по умолчанию оставалась бы там, где она есть.
console.log(this) //logs Window/global object var arr = [1,2,3]; arr.map(function(num) { //more on this below console.log(this.num); //logs [undefined, undefined, undefined] })
Это довольно сложно, потому что оно автоматически привязывается к контексту, в котором вызывается метод, особенно в момент его вызова. Эту концепцию легко запомнить в небольшой программе с несколькими вызовами методов, но она может стать сложной по мере того, как ваша программа разрастается и методы одного объекта начинают вызывать методы другого объекта. Мы можем углубиться в это ниже.
Не волнуйтесь дети! У меня тоже есть примеры!
Помните, что хитрость заключается в том, чтобы сосредоточиться на том, что thisявляетсявызываемым при вызове. время. Чтобы представить это в перспективе, давайте воспользуемся методом call().
Примечание. Метод call() может принимать несколько параметров, но в основном он будет использоваться здесь, чтобы вручную установить эталонную цель для этого. .
Рассмотрим блок кода ниже:
var YellObj = { yell: function() { console.log('This IS...' + this.place); } }; var Leonidas = { place: 'Sparta!!!' }; var Xerxes = { place: 'Not Sparta!!!' }; //just to get you thinking var soldier = { place: Leonidas.place + '..Or is it?' }; var battleCry = YellObj.yell; battleCry.call(); //logs 'This IS...undefined' battleCry.call(Leonidas); //logs 'This IS...Sparta!!!' battleCry.call(Xerxes); //logs 'This IS...Not Sparta!!!' battleCry.call(soldier); //logs 'This IS...Sparta..Or is it?'
Первый параметр call() передает ссылку, к которой this может привязываться, к методу обсуждаемый . Давайте посмотрим, что происходит при каждом вызове.
Первый вызов ==> Аргументы не переданы
Это привязывается к окну или глобальному объекту. Метод battleCry() обращается к глобальному объекту в поисках свойства/метода под названием «место». Это не существует и, таким образом, возвращает «неопределенное».
Второй и третий вызов ==> Объекты, переданные в качестве ссылки
Это привязывается к соответствующему объекту для каждого вызова. Методы battleCry() ищут свойство «место» в своих объектах и успешно заменяют переменную в журнале.
Последний звонок
Это привязывается к объекту солдата. Свойство «место» объекта солдата действительно ссылается на свойство «место» в объекте Леонидас, но привязка thisгарантирует, что во время вызова контекст передается в battleCry() будет объектом солдата.
Основные случаи того, что «это» связывает с
В большинстве случаев лучший способ определить, к чему относится this, заключается в том, что находится слева от точки AT во время вызова. Да, я сказал последнюю часть уже три раза, так что, может быть, просто может быть… это важно.
ПОЖАЛУЙСТА, помните последнюю часть, чтобы не выглядеть полным инструментом перед всеми вашими друзьями-разработчиками JS!
Вот еще несколько примеров, которые помогут вам понять это… ха-ха-ха-ха… каламбуры классные!
//Set up var thisLogger = function() { console.log(this); } var obj1 = { methodX: thisLogger } var obj2 = { methodY: obj1.methodX } //Invocation Types //global reference console.log(this); //logs Window/global object //free function invocation thisLogger(); //logs Window/global object //call() manual method thisLogger.call(obj2); //logs obj2 //basic method invocation obj1.methodX(); //logs obj1 obj2.methodY(); //logs obj2 //constructor var thatLogger = new thisLogger() //logs thatLogger(new object)
Разве это не было весело?
Надеюсь, вы узнали что-то сегодня! Если вам интересно, как этоможноиспользовать при создании вашей программы, ознакомьтесь с моим предыдущим постом о шаблонах создания экземпляров, чтобы увидеть это в действии.
P.S. Я написал «это» 50 раз (теперь 51) в этом посте (черт возьми, сейчас 52)…