Каждый так называемый разработчик JavaScript должен быть в состоянии ответить на этот фундаментальный вопрос: что такое «это»?
Однако на самом деле вокруг «существует большая путаница». это ключевое слово в мире ООП JS, как для новичков,
так и для опытных разработчиков, не так ли?? Я имею в виду, пытались ли вы когда-нибудь использовать «это» в своем коде JavaScript
только для того, чтобы обнаружить, что это не делает то, что вы ожидали? Я знаю, что да!
И, к сожалению, это разочарование заставило большинство из нас выбрать другие, не такие элегантные и менее пригодные для повторного использования решения для наших алгоритмов.
Если вы понимаете это, эта статья для вас. Сегодня я стремлюсь положить конец этой ситуации и открыть для нас дверь в совершенно новый мир
возможностей; вот оно.
Чтобы понять, что такое ключевое слово «this» в JavaScript, нам сначала нужно понять, чем «this» не является; и что может быть лучше,
сделать это, чем несколько примеров? Давайте посмотрим на следующие фрагменты:
const obj = { name: 'John', greet: `Hello, my name is ${this.name}`, }; console.log(obj.greet); //Hello, my name is //undefined
Хм?
так что, если написать это так?:
const person = { name: 'John', greet: () => { console.log(`Hello, my name is ${this.name}`); } }; person.greet(); //Hello, my name is //undefined
нет, тоже не работает!
(помните, у стрелочных функций нет «this» для привязки).
Хорошо… Давайте посмотрим на это другое:
function foo(num) { console.log( "foo: " + num ); // keep track of how many times `foo` is called this.count++; } foo.count = 0; for (let i = 0; i < 3; i++) { foo(i); } //foo: 0 //foo: 1 //foo: 2 console.log( foo.count ); // ← how many times was `foo` called? // 0
ВТФ!
… понял идею? Эти примеры показывают, что ошибочное представление о том, что this относится к области действия, в которой оно объявлено, является наиболее распространенной ошибкой в этом контексте.
Давайте рассмотрим еще один пример:
function foo() { var a = 2; this.bar(); } function bar() { console.log( this.a ); } foo(); //undefined
Как бы глупо это ни звучало, подобные фрагменты были опубликованы на справочных форумах, где спрашивали, почему это не работает. Код пытается создать мост между областью действия foo()
` и областью действия bar()
`, чтобы bar()
`имела доступ к a
внутри foo()
`. Создать такой мост невозможно.
Итак, теперь, когда у нас есть более четкое представление о том, что "это" не, давайте взглянем на то, что "это" на самом деле является .
Чтобы сделать это, мы должны спросить себя, если «это» не определяется областью действия, в которой оно объявлено, то чем определяется это?? И это, друзья мои,
является ключом к пониманию всего этого.
давайте теперь взглянем на следующие очень простые фрагменты:
Пример 1:
console.log(this); //Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, …}
Хорошо, по крайней мере, теперь мы не получаем «неопределенное».
Здесь this
относится к глобальному объекту ( window
при запуске в среде браузера) по умолчанию.
Мы можем вызывать ‘this’ из любой области, если нет других помех привязки. Вот пример 1.1:
function foo() { console.log( this.a ); } var a = 3; foo(); // 3
Это называется «Привязка по умолчанию».
Примечание. Если действует строгийрежим, глобальный объект не подходит для привязки
по умолчанию, поэтому для 'this' вместо этого устанавливается значение не определено
Пример 2:
const person = { name: 'John', greet() { console.log(`Hello, my name is ${this.name}`); } }; person.greet(); //'Hello, my name is John'
Итак, теперь это работает?
В этом примере this
относится к объекту person
, поскольку greet
метод принадлежит объекту person
. Вот пример 2.1:
function foo() { console.log( this.a ); } var obj = { a: 3, foo: foo }; obj.foo(); // 3
Обратите внимание, что функция, которую мы здесь вызываем, не принадлежит объекту obj
, а только добавляется как ссылка, но при вызове мы используем объект как контекст.
Это называется «Неявное связывание».
Пример 3:
function greet() { console.log(`Hello, my name is ${this.name}`); } const person = { name: 'John' }; greet.call(person); //Hello, my name is John
В этом примере this
относится к объекту person
, поскольку он передается в качестве первого аргумента метода call()
. Это называется «Явное связывание».
Пример 4:
function Person(name) { this.name = name; } const person = new Person('John'); console.log(person.name); //John
В этом примере this
относится к новому объекту, созданному функцией-конструктором Person. Это называется
«Новая привязка».
Как эти примеры помогают нам ответить на ключевой вопрос, чем определяется «это»? Все эти примеры показывают, что this определяется
способом вызова содержащей его функции. И это ключ к пониманию «этого».
Другими словами, существует 4 основных правила, определяющих, как работает это:
1.- Привязка по умолчанию: если 'this' не привязан ни к какому объекту по каким-либо другим правилам, он ссылается на глобальный объект. , который обычно является объектом window в среде браузера.
2.- Неявное связывание: если 'this' используется внутри метода объекта, it ссылается на объект, которому принадлежит метод.
3.- Явная привязка: если 'this' используется с call(), apply(), или bind(), it ссылается на объект, который передается в качестве первого аргумента этим методам.
4.- Новая привязка: если 'this' используется с функцией конструктора, it ссылается на объект который создается функцией-конструктором.
Итак, в заключение, "это" определяется не тем, где оно объявлено, а тем, как это вызвано. Думайте о этом как о заполнителе, который вы позже будете заполнять по своему усмотрению.
Ключевое слово "это – это нечто большее, но, освоив эти 4 основных правила, и с практикой мы сможем начать чувствовать себя более уверенно при использовании this и начать писать более элегантный и пригодный для повторного использования код.
Наконец, я хотел бы отдать должное прекрасному материалу для чтения и его создателю, который помог мне лучше понять концепцию «этого», о которой я немного беспокоился, и я чувствую, что я на хороший ряд с этого момента! В частности, к этой теме, модулю This & ObjectsPrototypes, из сказочного:
Кайл Симпсон «Вы не знаете JavaScript.
Я надеюсь, что это было полезно! Спасибо за чтение!!!