Ultimate Guide to Getters и сетери в JavaScript
абсорбиращи смеси и инкубатори са използвани функции или методи получавам и комплект стойностите на променливите. Концепцията на getter-setter е често срещано в компютърното програмиране: почти всички езици за програмиране на високо ниво идват с набор от синтаксис за прилагане на getters и setters, включително JavaScipt.
В този пост ще видим какви са създателите на getters и как създайте и използвайте ги в JavaScript.
Вземане-установяване и капсулиране
Идеята за гетерите и сеттерите винаги се споменава във връзка с капсулиране. Капсулирането може да бъде разбира се по два начина.
Първо, това е създаването на от данни привличат създателите трио за достъп и промяна на тези данни. Тази дефиниция е полезна, когато някои операции, като например валидиране, трябва да бъдат на данните преди да го запазите или прегледате, те ще осигурят идеалния дом за него.
Второ, има по-строга дефиниция, според която се прави капсулиране скриване на данни, да го направи недостъпен от друг код, освен чрез геттерите и сеттерите. По този начин няма да свършим случайно презаписване на важни данни с друг код в програмата.
Създайте getters и сетатори
1. С методи
Тъй като гетерите и сеттерите са основно функции които извличат / променят стойност, има повече от един начин да ги създавате и използвате. Първият начин е:
var obj = foo: 'това е стойността на foo', getFoo: function () return this.foo; , setFoo: функция (val) this.foo = val; console.log (obj.getFoo ()); // "това е стойността на foo" obj.setFoo ('hello'); console.log (obj.getFoo ()); // "Здравейте"
Това е най-простият начин да се създадат геттери и сеттери. Има имот Foo
и има два метода: getFoo
и setFoo
да се връщане и присвояване на стойност към този имот.
2. С ключови думи
Още “официален” и надежден начин за създаване на getters и сетатори е чрез използване на получавам
и комплект
ключови думи.
Да се създайте геттер, поставете получавам
ключова дума пред декларация за функция, която ще служи като метод на getter, и ще използва комплект
ключова дума по същия начин създайте сетер. Синтаксисът е както следва:
var obj = fooVal: 'това е стойността на foo', получи foo () върнете този.fooVal; , задайте foo (val) this.fooVal = val; console.log (obj.foo); // "това е стойността на foo" obj.foo = 'hello'; console.log (obj.foo); // "Здравейте"
Имайте предвид, че данните могат да бъдат само съхранявани под име на собственост (fooVal
) това е различен от името на методите на getter-setter (Foo
) защото имот притежаващ гетер-сеттер не могат да държат данните също.
Кой път е по-добър?
Ако решите да създадете getters и setters с ключови думи, можете да използвате оператор за задаване на данни и точка оператор, за да получите данните, по същия начин, по който бихте отворили / задали стойността на редовна собственост.
Въпреки това, ако изберете първия начин за кодиране на getters и setters, трябва да извикате метода setter и getter използвайки синтаксиса на функционалното повикване защото те са типични функции (нищо особено като тези, създадени с помощта на получавам
и комплект
ключови думи).
Също така има шанс да попаднете случайно присвояване на друга стойност към свойствата, които държат тези методи на гетер-сеттер и ги загуби напълно! Нещо, за което не трябва да се тревожите в по-късния метод.
Така че, можете да видите защо казах втората техника е по-стабилна.
Предотвратяване на презаписване
Ако по някаква причина предпочитате първата техника, направете свойствата, държащи методите на getter-setter Само за четене чрез създаването им използвайки Object.defineProperties
. Свойства, създадени чрез Object.defineProperties
, Object.defineProperty
и Reflect.defineProperty
автоматично конфигуриране да се writable: false
което означава Само за четене:
/ * Защита от презаписване * / var obj = foo: 'това е стойността на foo'; Object.defineProperties (obj, 'getFoo': value: function () return this.foo;, 'setFoo': стойност: функция (val) this.foo = val;); obj.getFoo = 66; // getFoo няма да бъде презаписана! console.log (obj.getFoo ()); // "това е стойността на foo"
Операции вътре в гетерите и сеттери
След като въведете геттерите и установителите, можете да продължите напред извършва операции по данните преди да я промените или върнете.
В кода по-долу, в getter функцията са данните свързва се с низ преди връщането и в функцията за настройка на дали стойността е число или не се извършва преди актуализирането п
.
var obj = n: 67, get id () return 'ID е:' + 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"
Защита на данните с помощта на getters и setters
Досега обхващахме използването на getters и setters в първия контекст на капсулиране. Да преминем към второто, т.е. скриване на данни от външен код с помощта на геттери и сетатори.
Незащитени данни
Създаването на getters и setters не означава, че данните могат да бъдат достъпни и променени само чрез тези методи. В следващия пример това е променени директно без докосване на методите за получаване и установяване:
var obj = fooVal: 'това е стойността на foo', получи foo () върнете този.fooVal; , задайте foo (val) this.fooVal = val; obj.fooVal = 'здравей'; console.log (obj.foo); // "Здравейте"
Не използвахме сетера, но директно промени данните (fooVal
). Данните, които първоначално сме задали вътре OBJ
вече няма! За да предотвратите това да се случи (случайно), вие нужда от някаква защита за вашите данни. Можете да добавите това от ограничаване на обхвата на разположение на вашите данни. Можете да го направите и от двете блок обхват или функция на обхвата.
1. Блокиране на обхвата
Един от начините е да използвайте поле на блок вътре в които данните ще бъдат определени с помощта на позволявам
ключова дума, която ограничава обхвата му към този блок.
А обхват на блока може да се създаде чрез поставяне на кода вътре в чифт къдрави скоби. Всеки път, когато създавате поле на блок, уверете се, че сте го направили Оставете коментар над него с молба за скобите да бъдат оставени сами, така че никой премахва скобите по погрешка мисля, че са някои допълнителни излишни скоби в кода или добавете етикет в обхвата на блока.
/ * BLOCK SCOPE, оставете скобите сами! * / нека 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 и setters?
Сега идва големият въпрос: започвате ли да присвоявате гетери и сетатори към всичките ви данни сега?
Ако ти си скриване на данни, тогава има няма друг избор.
Но ако вашите данни се вижда от друг код е добре, все още трябва да използвате getters установители само за да го свърже с код който извършва някои операции върху него? бих казал да. код добавя много скоро. Създаване на микро единици с индивидуални данни със собствен гетер-сеттер ви осигурява определена независимост да работят по споменатите данни, без да засягат други части от кода.