This в Javascript представляет объект, выполняющий текущую функцию.
Если функция в объекте (так называемый метод), this ссылается на объект. Если this находится в обычной функции, this ссылается на глобальный объект, который является объектом Window в браузерах и глобальным объектом в узле.
/* 'this' in methods */ const video = { title: 'a', play() { console.log(this) } } video.play() // it will print the video object /* we can also add a function after the object declaration */ video.stop = function() = { console.log(this); } video.stop() // also video object /* 'this' in a regular function */ function playVideo() { console.log(this) } playVideo() // it will print the Window object /* what about constructor? */ function Video(title) { this.title = title; console.log(this) } const v = new Video('myVideo') // return Video Object
Давайте посмотрим на следующий пример.
const video = { title: 'title', tags: ['a','b','c'], showTags() { this.tags.forEach(function(tag) { console.log(this.title, tag) }) } } video.showTags() // undefined "a" undefined "b" undefined "c"
Там написано не определено. 🤯 Это потому, что он ссылается на объект Window. Функция внутри forEach является функцией обратного вызова. Функция обратного вызова — это обычная функция. Это не метод объекта видео. Итак, как мы можем исправить это, чтобы отображать заголовок перед каждым тегом?
- Метод forEach имеет два параметра. Первая — это функция обратного вызова, а вторая — thisArg. Мы можем передать объект, и this будет ссылаться на него.
const video = { title: 'title', tags: ['a','b','c'], showTags() { this.tags.forEach(function(tag) { console.log(this.title, tag) }, {firstName: 'jay', lastName: 'Oh'}) } } video.showTags() // {firstName: 'jay', lastName: 'Oh'} "a" ...
Но мы знаем, что нам нужен заголовок вместо пользовательского объекта. Это будет ссылаться на видео во втором параметре. Итак, это будет this.title
const video = { title: 'title', tags: ['a','b','c'], showTags() { this.tags.forEach(function(tag) { console.log(this.title, tag) }, this.title) } } video.showTags() // title a, title b, title c
Вместо того, чтобы полагаться на второй параметр forEach, thisArg, мы можем использовать функцию стрелки для привязки this.
const video = { title: 'title', tags: ['a','b','c'], showTags() { // using the arrow function this.tags.forEach((tag) => { console.log(this.title, tag) }) } } video.showTags() // title a, title b, title c
Я надеюсь, что это помогает :)