Давным-давно, в далекой-далекой галактике...

Раньше я зарабатывал на жизнь разливом напитков из-за барной стойки. Мои коллеги и я предполагали, что мохито изобрел какой-то бедный ублюдок, поклявшийся отомстить бармену, который пригласил его мать на вкусный ужин из морепродуктов и больше никогда ей не звонил (да, вы правы. Справочник ведущего!И спросите у любого бармена, они согласятся). В любом случае, после того, как на прошлой неделе вы разобрались с ловушками ключевого слова 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)…