Розуміння області видимості в об’єктно-орієнтованому JavaScript
Мітки: веб-розробка, javascript
Понимание области видимости в объектно-ориентированном JavaScript
Understanding scope in object oriented JavaScript
| ← 6 інструментів для того щоб бути ефективним Web-розробником | 10 кроків до швидкого вивчення нової мови програмування → |
Коли ви думаєте про ключове слово this, ви, напевно, вважаєте, що воно відноситься до поточного екземпляру класу. Це вірно для більшості об’єктно-орієнтованих мов, як C# та Java.
Наприклад, я міг би використовувати this в C# таким чином:
Прибрати підсвітку коду
В цьому прикладі ви можете побачити ілюстрацію цього. В C# та Java, this завжди відноситься до екземпляру класу.
Отже знаючи це, ви напевно вирішите, що та сама ситуація буде в JavaScript і його this. Проте, це не той випадок. Як і більшість написання об’єктно-орієнтованого коду JavaScript, this поводить себе по-різному в деяких випадках. В залежності від того як ви використовуєте this, він може не завжди вказувати на екземпляр класу.
Прибрати підсвітку коду
В цьому прикладі все працює саме так як і в прикладі з C#, але давайте подивимося на приклад, де речі можуть працювати неправильно, якщо не знати деяких правил.
Прибрати підсвітку коду
У своїх прикладах, для виводу даних я використовую об’єкт console з Firebug.
Що ж не так з цим прикладом? Все виглядає правильно і повинно працювати, чи не так? Добре, оперуючи припущенням, що this завжди вказує на екземпляр класу, даний приклад абсолютно вірний. Проте, ми використовуємо JavaScript і не повинні дивуватись тому, що він робить речі дещо інакше.
При виклику publicMethod(), буде виведено:
Прибрати підсвітку коду
Причина, по котрій this.publicProperty дорівнює undefined, в тому, що коли вводиться приватний метод, область видимості this змінюється. Воно більше не означає поточний екземпляр класу «WrongClass», тепер воно означає поточний екземпляр функції «privateMethod».
Інша ситуація, де область видимості this повинна була б змінитися, це коли воно працює з обробником подій.
Прибрати підсвітку коду
В цьому прикладі, this буде вказувати на елемент «button». Існує багато випадків зміни області видимості, з якими ви повинні бути знайомі, коли маєте справу з об’єктно-орієнтованими технологіями.
Повернемося до нашого прикладу з «WrongClass». Я покажу Вам, як зробити, щоб цей приклад працював так, як ви цього очікували спочатку.
Прибрати підсвітку коду
Ви помітили, що я об’явив в коді нову змінну self. Я присвоїв цій змінній значення this. Це дозволило мені використовувати змінну «self» в буд-який час, коли мені потрібно звернутися до екземпляру класу, не турбуючись при цьому про область видимості.
Ви можете назвати вашу змінну як завгодно, але «self» являється загальною практикою. Отже, зараз в «privateMethod», коли викликаєш «publicProperty», використовується «self» і воно виведе відповідне значення.
Прибрати підсвітку коду
Оригінал: Understanding scope in object oriented JavaScript
Наприклад, я міг би використовувати this в C# таким чином:
Прибрати підсвітку коду
1 2 3 4 5 6 | class Cat { string _name; public Cat(string name) { this._name = name; } } |
В цьому прикладі ви можете побачити ілюстрацію цього. В C# та Java, this завжди відноситься до екземпляру класу.
Отже знаючи це, ви напевно вирішите, що та сама ситуація буде в JavaScript і його this. Проте, це не той випадок. Як і більшість написання об’єктно-орієнтованого коду JavaScript, this поводить себе по-різному в деяких випадках. В залежності від того як ви використовуєте this, він може не завжди вказувати на екземпляр класу.
Прибрати підсвітку коду
1 2 3 | function Cat(name) { this.Name = name; } |
В цьому прикладі все працює саме так як і в прикладі з C#, але давайте подивимося на приклад, де речі можуть працювати неправильно, якщо не знати деяких правил.
Прибрати підсвітку коду
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var wrong = new WrongClass(); wrong.publicMethod(); function WrongClass() { this.publicProperty = 'props'; this.publicMethod = function() { console.log('public method'); privateMethod(); }; var privateMethod = function() { console.log('private method'); console.log('public property equals ' + this.publicProperty); }; } |
У своїх прикладах, для виводу даних я використовую об’єкт console з Firebug.
Що ж не так з цим прикладом? Все виглядає правильно і повинно працювати, чи не так? Добре, оперуючи припущенням, що this завжди вказує на екземпляр класу, даний приклад абсолютно вірний. Проте, ми використовуємо JavaScript і не повинні дивуватись тому, що він робить речі дещо інакше.
При виклику publicMethod(), буде виведено:
Прибрати підсвітку коду
1 2 3 | >>> public method
>>> private method
>>> public property equals undefined |
Причина, по котрій this.publicProperty дорівнює undefined, в тому, що коли вводиться приватний метод, область видимості this змінюється. Воно більше не означає поточний екземпляр класу «WrongClass», тепер воно означає поточний екземпляр функції «privateMethod».
Інша ситуація, де область видимості this повинна була б змінитися, це коли воно працює з обробником подій.
Прибрати підсвітку коду
1 2 3 | document.getElementById('button').onclick = function() { alert(this.id); } |
В цьому прикладі, this буде вказувати на елемент «button». Існує багато випадків зміни області видимості, з якими ви повинні бути знайомі, коли маєте справу з об’єктно-орієнтованими технологіями.
Повернемося до нашого прикладу з «WrongClass». Я покажу Вам, як зробити, щоб цей приклад працював так, як ви цього очікували спочатку.
Прибрати підсвітку коду
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var right = new RightClass(); right.publicMethod(); function RightClass() { var self = this; this.publicProperty = 'props'; this.publicMethod = function() { console.log('public method'); privateMethod(); }; var privateMethod = function() { console.log('private method'); console.log('public property equals ' + self.publicProperty); }; } |
Ви помітили, що я об’явив в коді нову змінну self. Я присвоїв цій змінній значення this. Це дозволило мені використовувати змінну «self» в буд-який час, коли мені потрібно звернутися до екземпляру класу, не турбуючись при цьому про область видимості.
Ви можете назвати вашу змінну як завгодно, але «self» являється загальною практикою. Отже, зараз в «privateMethod», коли викликаєш «publicProperty», використовується «self» і воно виведе відповідне значення.
Прибрати підсвітку коду
1 2 3 | >>> public method
>>> private method
>>> public property equals props |
Оригінал: Understanding scope in object oriented JavaScript
Рейтинг:




<< Ви можете поставити оцінку цій статтіПодібні статті:
6 інструментів для того щоб бути ефективним Web-розробником
Введення в мистецтво модульного тестування в PHP
Інтеграція FCKeditor в Zend_Form
Автоматизоване тестування з використанням Zend Framework
Паттерн кешування для моделей