JavaScript виконання коду JavaScript підключення зовнішнього файлу JavaScript console.log JavaScript змінні і константи JavaScript типи даних JavaScript операції зі змінними JavaScript перетворення даних JavaScript масиви JavaScript умовні конструкції JavaScript цикли JavaScript функції JavaScript область видимості змінних JavaScript замикання і функції IIFE JavaScript Паттерн Модуль JavaScript рекурсивні функції JavaScript перевизначення функцій JavaScript hoisting JavaScript передача параметрів за значенням і за посиланням JavaScript стрілочні функції JavaScript ООП Object JavaScript ООП вкладені об'єкти і масиви в об'єктах JavaScript ООП перевірка наявності і перебір методів і властивостей JavaScript ООП об'єкти у функціях JavaScript ООП конструктори об'єктів JavaScript ООП розширення об'єктів. prototype JavaScript ООП інкапсуляція JavaScript ООП Функція як об'єкт. Методи call і apply JavaScript ООП спадкування JavaScript ООП Ключове слово this JavaScript ООП Object destructuring JavaScript ООП класи JavaScript ООП Date. Робота з датами JavaScript Об'єкт Math. математичні операції JavaScript Об'єкт Array. Робота з масивами JavaScript ООП об'єкт Number JavaScript String JavaScript String Об'єкт RegExp. Регулярні вирази JavaScript String Регулярні вирази в методах String JavaScript String Синтаксис регулярних виразів JavaScript Робота з браузером і BOM JavaScript діалогові вікна JavaScript Історія браузера. об'єкт history JavaScript об'єкт location JavaScript об'єкт navigator JavaScript таймери JavaScript DOM Введення JavaScript DOM Об'єкт document. Пошук елементів JavaScript DOM Властивості об'єкта document JavaScript DOM Об'єкт Node. Навігація по DOM JavaScript DOM Створення, додавання і видалення елементів веб-сторінки JavaScript DOM Об'єкт Element. управління елементами JavaScript DOM Зміна стилю елементів JavaScript події. Введення в обробку подій. JavaScript події обробники JavaScript події. об'єкт Event JavaScript події. поширення подій JavaScript події миші JavaScript події клавіатури JavaScript FORMS. Форми і їх елементи JavaScript FORMS. Кнопки JavaScript FORMS. текстові поля JavaScript FORMS. Прапорці та перемикачі JavaScript FORMS. Список select JavaScript JSON JavaScript зберігання даних. cookie JavaScript зберігання даних. Web Storage JavaScript Collection. Ітератори JavaScript Collection. Генератори JavaScript Collection. Множина Set JavaScript Collection. Map JavaScript Collection. WeakSet і WeakMap JavaScript AJAX. XMLHttpRequest JavaScript AJAX. Відправка даних JavaScript AJAX. Promise в Ajax-запитах

JavaScript ООП Ключове слово this


Ключове слово this

Поведінка ключового слова this залежить від контексту, в якому воно використовується, і від того, в якому режимі воно використовується - строгому або нестрогому.


Глобальний контекст

У глобальному контексті this посилається на глобальний об'єкт. В даному випадку поведінка не залежить від режиму (строгий або нестрогий):

this.alert("global alert");
this.console.log("global console");
 
var currentDocument = this.document;

Контекст функції

Якщо скрипт запускається в строгому режимі (директива "use strict" ), то this посилається безпосередньо на контекст функції. Інакше this посилається на зовнішній контекст. наприклад:

function foo(){
    var bar = "bar2";
    console.log(this.bar);
}
 
var bar = "bar1";
 
foo();  // bar1

Сенсу використання this в даному випадку немає, так як ми могли б безпосередньо використовувати локальну змінну.

Якби ми використовували строгий режим, то this в цьому випадку мало б значення undefined :

"use strict";

function foo(){
    var bar = "bar2";
    console.log(this.bar);
}
 
var bar = "bar1";
 
foo();  // Помилка - this - undefined

Контекст обєкта

В контексті об'єкта, в тому числі в його методах, ключове слово this посилається на цей же об'єкт:

var o = {
    bar: "bar3",
    foo: function(){
        console.log(this.bar);
    }
}

var bar = "bar1";
o.foo();           // bar3

приклади

Розглянемо більш складний приклад:

function foo(){
    var bar = "bar2";
    console.log(this.bar);
}
 
var o3 = {bar:"bar3", foo: foo};
var o4 = {bar:"bar4", foo: foo};
 
var bar = "bar1";
 
foo();      // bar1
o3.foo();   // bar3
o4.foo();   // bar4

Тут визначена глобальна змінна bar . І також у функції foo визначена локальна змінна bar . Значення якої змінної буде виводитися в функції foo ?

Функція foo виводить значення глобальної змінної, так як даний скрипт запускається в нестрогому режимі, а значить ключеое слово this в функції foo посилається на зовнішній контекст.

Інакше справа йде з об'єктами. Вони визначають свій власний контекст, в якому існує своя властивість bar . І при виклику методу foo зовнішнім контекстом по відношенню до функції буде контекст об'єктів o3 і o4 .

Подібна поведінка може привести до деякого нерозуміння в окремих випадках. Так, розглянемо іншу ситуацію:

var o1 = {
    bar: "bar1",
    foo: function(){
        console.log(this.bar);
    }
}
var o2 = {bar: "bar2", foo: o1.foo};
 
var bar = "bar3";
var foo = o1.foo;
 
o1.foo();   // bar1
o2.foo();   // bar2
foo();      // bar3

Незважаючи на те, що об'єкт o2 використовує метод foo з об'єкта o1 , проте функція o1.foo також буде шукати значення для this.bar в зовнішньому котексті, тобто в контексті об'єкта o2 . А в об'єкті o2 це значення дорівнює bar: "bar2" .

Те ж саме з глобальною змінною foo , яка посилається на ту ж функцію, що і метод o1.foo . У цьому випадку також буде відбуватися пошук значення для this.bar у зовнішньому контексті, тобто в глобальному контексті, де визначена змінна var bar = "bar3" .

Однак якщо ми викликаємо функцію з іншої функції, що викликається функція також буде використовувати зовнішній контекст:

var bar = "bar2";
 
function daz(){

    var bar = "bar5";

    function maz(){
        console.log(this.bar);
    }

    maz();

}

daz();  // bar2

Тут функція daz як this.bar використовує значення змінної bar з зовнішнього контексту, тобто значення глобальної змінної bar . Функція maz також в якості this.bar використовує значення змінної bar з зовнішнього контексту, а це значення this.bar з зовнішньої функції daz , яке в свою чергу представляє значення глобальної змінної bar . Тому в підсумку консоль виведе "bar2" , а не "bar5" .


явна прив'язка

За допомогою методів call() і  apply() можна задати явну прив'язку функції до певного контексту:

function foo(){
    console.log(this.bar);
}
 
var o3 = {bar: "bar3"}
var bar = "bar1";

foo();          // bar1
foo.apply(o3);  // bar3

// або
// foo.call(o3);

У другому випадку функція foo прив'язується до об'єкта o3 , який і визначає її контекст. Тому в другому випадку консоль виведе "bar3" .


Метод bind

Метод f.bind(o) дозволяє створити нову функцію з тим же тілом і областю видимості, що і функція foo , але з прив'язкою до об'єкта o3 :

function foo(){
    console.log(this.bar);
}
 
var o3 = {bar: "bar3"}
var bar = "bar1";
foo();  // bar1
var func = foo.bind(o3);
func(); // bar3

this і стрілочні функції

При роботі з декількома контекстами ми змушені враховувати, в якому контексті визначається змінна. Наприклад, візьмемо наступний код:

var school ={

    title: "Oxford",
    courses: ["JavaScript", "TypeScript", "Java", "Go"],

    printCourses: function(){
        this.courses.forEach(function(course){
            console.log(this.title, course);
        })
    }

}

school.printCourses();

Функція printCourses проходить по всім курсам з масиву і при їх виведенні випереджає їх значенням властивості title . Однак на консолі при запуску програми ми побачимо наступне:

this.title[/tag_code] не визначене, тому що  this як контекст об'єкта заміщається глобальним контекстом. У цьому випадку нам треба передати подібне значення  this.title  або весь контекст об'єкта.[/p]

[code]var school ={
    title: "Oxford",

    courses: ["JavaScript", "TypeScript", "Java", "Go"],

    printCourses: function(){
        var that = this;
        this.courses.forEach(function(course){
            console.log(that.title, course);
        })
    }

}

school.printCourses();

Стрілочні функції також дозволяють вирішити дану проблему:

var school ={
    title: "Oxford",
    courses: ["JavaScript", "TypeScript", "Java", "Go"],

    printCourses: function(){
        this.courses.forEach((course)=>console.log(this.title, course))
    }

}

school.printCourses();

Контекстом для стрілочної функції в даному випадку буде виступати контекст об'єкта school . Відповідно, нам непотрібно визначати додаткові змінні для передачі даних в функцію.


Наш партнер:
beta test mp3 playlist downloader