Остаточний посібник для отримувачів і сеттерів у JavaScript
Геттери і сеттерів є функціями або методами, що використовуються отримати і набір значення змінних. Концепція геттера-сеттера поширене в комп'ютерному програмуванні: майже всі мови програмування високого рівня поставляються з набором синтаксису для реалізації геттерів і сеттерів, включаючи JavaScipt.
У цій посаді ми побачимо, що таке і як створювати та використовувати їх у JavaScript.
Геттерів і інкапсуляція
Ідея геттерів і сеттерів завжди згадується у поєднанні з інкапсуляцією. Інкапсуляція може бути розуміється двома способами.
По-перше, це створення дані-отримувачі-сеттери тріо, щоб отримати доступ і змінити ці дані. Це визначення корисно, коли деякі операції, такі як перевірка, мають бути на даних перед тим, як зберігати або переглядати його, вони стануть ідеальним місцем для нього.
По-друге, існує суворіше визначення, згідно з яким робиться інкапсуляція приховати дані, зробити його недоступним з іншого коду, крім через геттерів і сеттерів. Таким чином, ми не закінчимося випадково перезаписати важливі дані з іншим кодом програми.
Створіть геттерів і сеттерів
1. З методами
Оскільки геттери та сеттери є в основному функції які отримують / змінюють значення, є більше ніж один спосіб створювати і використовувати їх. Перший спосіб:
var obj = foo: 'це значення foo', getFoo: function () return this.foo; , setFoo: function (val) this.foo = val; console.log (obj.getFoo ()); // "це значення foo" obj.setFoo ('hello'); console.log (obj.getFoo ()); // "Здрастуйте"
Це найпростіший спосіб створення геттерів і сеттерів. Є власність foo
Є два способи: getFoo
і setFoo
до повернути і призначити значення до цієї власності.
2. За допомогою ключових слів
Більше “офіційний” і надійний спосіб створення геттерів і сеттерів - за допомогою отримати
і набір
ключові слова.
До створити геттер, місце отримати
ключове слово перед декларацією функції, яка буде служити методом getter, і використовувати набір
ключове слово так само створити сеттер. Синтаксис такий:
var obj = fooVal: 'це значення foo', get foo () return this.fooVal; , встановіть foo (val) this.fooVal = val; console.log (obj.foo); // "це значення foo" obj.foo = 'hello'; console.log (obj.foo); // "Здрастуйте"
Зверніть увагу, що дані можуть бути тільки зберігається під назвою властивості (fooVal
) це інший від назви методів getter-setter (foo
) через властивість, що утримує гетер-сеттер не може зберігати дані так само.
Який шлях кращий?
Якщо ви вирішите створити getters і сеттери з ключовими словами, ви можете використовувати призначення оператора для встановлення даних і оператор точки для отримання даних, так само, як ви б мали доступ / встановлювали значення звичайної властивості.
Однак, якщо ви обираєте перший спосіб кодування геттерів і сеттерів, вам доведеться викликати сетер і геттер-методи використовуючи синтаксис виклику функції тому що вони є типовими функціями (нічого особливого, як ті, які створені за допомогою отримати
і набір
ключові слова).
Крім того, є шанс, що ви закінчите випадково призначення іншого значення до властивостей, які утримували ці методи getter-setter і втратити їх повністю! Щось не потрібно турбувати про пізніший метод.
Отже, ви можете зрозуміти, чому я сказав Друга техніка є більш надійною.
Запобігання перезапису
Якщо з якихось причин ви віддаєте перевагу першій техніці, зробіть властивості, що утримують методи getter-setter лише для читання шляхом їх створення використання Object.defineProperties
. Властивості, створені за допомогою Object.defineProperties
, Object.defineProperty
і Reflect.defineProperty
автоматично налаштувати до для запису: false
що означає лише для читання:
/ * Захист від перезапису * / var obj = foo: 'це значення foo'; Object.defineProperties (obj, 'getFoo': value: function () повернути this.foo;, 'setFoo': value: function (val) this.foo = val;); obj.getFoo = 66; // getFoo не буде перезаписаний! console.log (obj.getFoo ()); // "це значення foo"
Операції всередині геттерів і сеттерів
Як тільки ви ввели геттерів і сеттерів, ви можете піти далі виконувати операції над даними перед зміною або поверненням.
У наведеному нижче коді в геттер-функції знаходяться дані об'єднані з рядком перед поверненням, а в функції сеттера - перевірку чи є це число чи ні виконується перед оновленням n
.
var obj = n: 67, get id () return 'Ідентифікатор:' + this.n; , встановіть id (val) if (typeof val === 'number') this.n = val; console.log (obj.id); // "ID: 67" obj.id = 893; console.log (obj.id); // "ID: 893" obj.id = 'hello'; console.log (obj.id); // "ID: 893"
Захищайте дані геттерами та сеттерами
До цих пір ми розглядали використання геттерів і сеттерів у першому контексті інкапсуляції. Давайте перейдемо до другого, тобто як приховати дані з зовнішнього коду за допомогою геттерів і сеттерів.
Незахищені дані
Створення геттерів і сеттерів не означає, що дані можуть бути доступні і змінені тільки за допомогою цих методів. У наступному прикладі це змінилися безпосередньо не торкаючись методів геттера і сетера:
var obj = fooVal: 'це значення foo', get foo () return this.fooVal; , встановіть foo (val) this.fooVal = val; obj.fooVal = 'hello'; console.log (obj.foo); // "Здрастуйте"
Ми не користувалися сеттером, але безпосередньо змінили дані (fooVal
). Дані, які ми спочатку встановили всередині obj
вже немає! Щоб запобігти цьому (випадково), ви потрібний певний захист для ваших даних. Ви можете додати це за обмеження обсягу де доступні ваші дані. Ви можете це зробити блок визначення обсягу або Функція масштабування.
1. Блокувати визначення масштабу
Один із способів - це використовувати область блоку в яких дані будуть визначені за допомогою дозволяє
ключове слово, яке обмежує його сферу застосування до цього блоку.
A область блоку можна створити, розмістивши свій код всередині пари фігурних дужок. Всякий раз, коли ви створюєте область блоку, переконайтеся, що Залишити коментар над ним просять підтяжки залишатися на самоті, так що ніхто видаляє фігурні дужки помилково думаючи, що вони є деякими зайвими дужками в коді або додати мітку до області блоку.
/ * БЛОК ОБМЕЖЕННЯ, залиште брекети поодинці! * / let fooVal = 'це значення foo'; var obj = get foo () повернути fooVal; , встановіть foo (val) fooVal = val fooVal = 'hello'; // не буде впливати на fooVal всередині блоку console.log (obj.foo); // "це значення foo"
Зміна / створення fooVal
поза блоком не вплине fooVal
згадані всередині сеттерів сеттерів.
2. Функція визначення масштабу
Найбільш поширеним способом захисту даних за допомогою поля зору є зберігання даних всередині функції і повернення об'єкта з геттерами і сеттерами з цієї функції.
функція myobj () var fooVal = 'це значення foo'; return get foo () повернути fooVal; , встановіть foo (val) fooVal = val fooVal = 'hello'; // не вплине на наш оригінальний fooVal var obj = myobj (); console.log (obj.foo); // "це значення foo"
Об'єкт (з foo ()
Геттер-сетер всередині нього) повертається myobj ()
функція збережено в obj
, і потім obj
використовується зателефонуйте геттеру і сетеру.
3. Захист даних без визначення масштабу
Також можна захистити свої дані від перезапису без обмеження його обсягу. Логіка, що стоїть за цим, виглядає так: як можна змінити дані, якщо ви не знаєте, що називається?
Якщо дані мають a не так легко відтворюється ім'я змінної / властивості, ймовірно, ніхто (навіть самі) не перезапише його, присвоївши деякому значенню ім'я змінної / властивості.
var obj = s89274934764: 'це значення foo', get foo () return this.s89274934764; , встановлено foo (val) this.s89274934764 = val; console.log (obj.foo); // "це значення foo"
Подивіться, це один із способів виправити ситуацію. Хоча назва, яку я вибрав, не дуже хороша, ви також можете використовувати випадкові значення або символи створити імена власності, як це запропонував Дерік Бейлі в цьому блозі. Головна мета - це зберігати приховані дані з іншого коду і дозволити пару getter-setter отримати / оновити його.
Коли ви повинні використовувати getters і сеттерів?
Тепер виникає велике питання: ви починаєте призначати гетерів і сеттерів до всіх ваших даних зараз?
Якщо ви приховування даних, тоді є іншого вибору немає.
Але якщо ваші дані розглядаються інший код в порядку, вам все ще потрібно використовувати getters сеттерів просто для того, щоб поєднати його з кодом що виконує деякі операції над ним? Скажу так. Код дуже скоро. Створення мікро одиниць індивідуальних даних з власним геттер-сеттером надає вам певну незалежність працювати над цими даними, не впливаючи на інші частини коду.