Izpētiet JavaScript simbolus: to mērķi, izveidi, pielietojumu unikālām īpašību atslēgām, metadatu glabāšanai un nosaukumu konfliktu novēršanai. Iekļauti praktiski piemēri.
JavaScript simboli: unikālas īpašību atslēgas un metadati
JavaScript simboli, kas ieviesti ECMAScript 2015 (ES6), nodrošina mehānismu unikālu un nemaināmu īpašību atslēgu izveidei. Atšķirībā no virknēm vai skaitļiem, simboli garantēti ir unikāli visā jūsu JavaScript lietojumprogrammā. Tie piedāvā veidu, kā izvairīties no nosaukumu konfliktiem, pievienot metadatus objektiem, netraucējot esošajām īpašībām, un pielāgot objektu uzvedību. Šis raksts sniedz visaptverošu pārskatu par JavaScript simboliem, aptverot to izveidi, pielietojumu un labākās prakses.
Kas ir JavaScript simboli?
Simbols ir primitīvs datu tips JavaScript, līdzīgi kā skaitļi, virknes, Būla vērtības, null un undefined. Tomēr, atšķirībā no citiem primitīvajiem tipiem, simboli ir unikāli. Katru reizi, kad izveidojat simbolu, jūs saņemat pilnīgi jaunu, unikālu vērtību. Šī unikalitāte padara simbolus ideāli piemērotus:
- Unikālu īpašību atslēgu izveidei: Simbolu izmantošana kā īpašību atslēgas nodrošina, ka jūsu īpašības nesadursies ar esošajām īpašībām vai īpašībām, ko pievienojušas citas bibliotēkas vai moduļi.
- Metadatu glabāšanai: Simbolus var izmantot, lai pievienotu metadatus objektiem veidā, kas ir slēpts no standarta uzskaitīšanas metodēm, saglabājot objekta integritāti.
- Objektu uzvedības pielāgošanai: JavaScript nodrošina labi zināmu simbolu kopu, kas ļauj pielāgot, kā objekti uzvedas noteiktās situācijās, piemēram, kad tie tiek iterēti vai pārvērsti par virkni.
Simbolu izveide
Jūs izveidojat simbolu, izmantojot Symbol()
konstruktoru. Ir svarīgi atzīmēt, ka nevar izmantot new Symbol()
; simboli nav objekti, bet gan primitīvas vērtības.
Pamata simbolu izveide
Vienkāršākais veids, kā izveidot simbolu, ir:
const mySymbol = Symbol();
console.log(typeof mySymbol); // Izvade: symbol
Katrs Symbol()
izsaukums ģenerē jaunu, unikālu vērtību:
const symbol1 = Symbol();
const symbol2 = Symbol();
console.log(symbol1 === symbol2); // Izvade: false
Simbolu apraksti
Izveidojot simbolu, varat norādīt neobligātu virknes aprakstu. Šis apraksts ir noderīgs atkļūdošanai un reģistrēšanai, bet tas neietekmē simbola unikalitāti.
const mySymbol = Symbol("myDescription");
console.log(mySymbol.toString()); // Izvade: Symbol(myDescription)
Apraksts ir tikai informatīviem nolūkiem; divi simboli ar vienādu aprakstu joprojām ir unikāli:
const symbolA = Symbol("same description");
const symbolB = Symbol("same description");
console.log(symbolA === symbolB); // Izvade: false
Simbolu izmantošana kā īpašību atslēgas
Simboli ir īpaši noderīgi kā īpašību atslēgas, jo tie garantē unikalitāti, novēršot nosaukumu konfliktus, pievienojot īpašības objektiem.
Simbolu īpašību pievienošana
Jūs varat izmantot simbolus kā īpašību atslēgas tāpat kā virknes vai skaitļus:
const mySymbol = Symbol("myKey");
const myObject = {};
myObject[mySymbol] = "Sveiki, Simbol!";
console.log(myObject[mySymbol]); // Izvade: Sveiki, Simbol!
Nosaukumu konfliktu novēršana
Iedomājieties, ka strādājat ar trešās puses bibliotēku, kas pievieno īpašības objektiem. Jūs, iespējams, vēlēsities pievienot savas īpašības, neriskējot pārrakstīt esošās. Simboli nodrošina drošu veidu, kā to izdarīt:
// Trešās puses bibliotēka (simulēta)
const libraryObject = {
name: "Bibliotēkas Objekts",
version: "1.0"
};
// Jūsu kods
const mySecretKey = Symbol("mySecret");
libraryObject[mySecretKey] = "Pilnīgi slepena informācija";
console.log(libraryObject.name); // Izvade: Bibliotēkas Objekts
console.log(libraryObject[mySecretKey]); // Izvade: Pilnīgi slepena informācija
Šajā piemērā mySecretKey
nodrošina, ka jūsu īpašība nekonfliktē ar nevienu esošu īpašību libraryObject
.
Simbolu īpašību uzskaitīšana
Viena būtiska simbolu īpašību iezīme ir tā, ka tās ir slēptas no standarta uzskaitīšanas metodēm, piemēram, for...in
cikliem un Object.keys()
. Tas palīdz aizsargāt objektu integritāti un novērš nejaušu piekļuvi simbolu īpašībām vai to modificēšanu.
const mySymbol = Symbol("myKey");
const myObject = {
name: "Mans Objekts",
[mySymbol]: "Simbola Vērtība"
};
console.log(Object.keys(myObject)); // Izvade: ["name"]
for (let key in myObject) {
console.log(key); // Izvade: name
}
Lai piekļūtu simbolu īpašībām, jums jāizmanto Object.getOwnPropertySymbols()
, kas atgriež masīvu ar visām objekta simbolu īpašībām:
const mySymbol = Symbol("myKey");
const myObject = {
name: "Mans Objekts",
[mySymbol]: "Simbola Vērtība"
};
const symbolKeys = Object.getOwnPropertySymbols(myObject);
console.log(symbolKeys); // Izvade: [Symbol(myKey)]
console.log(myObject[symbolKeys[0]]); // Izvade: Simbola Vērtība
Labi zināmie simboli
JavaScript nodrošina iebūvētu simbolu kopu, kas pazīstami kā labi zināmie simboli, kuri pārstāv specifiskas uzvedības vai funkcionalitātes. Šie simboli ir Symbol
konstruktora īpašības (piemēram, Symbol.iterator
, Symbol.toStringTag
). Tie ļauj jums pielāgot, kā objekti uzvedas dažādos kontekstos.
Symbol.iterator
Symbol.iterator
ir simbols, kas definē objekta noklusējuma iteratoru. Kad objektam ir metode ar atslēgu Symbol.iterator
, tas kļūst iterējams, kas nozīmē, ka to varat izmantot ar for...of
cikliem un izklāšanas operatoru (...
).
Piemērs: Pielāgota iterējama objekta izveide
const myCollection = {
items: [1, 2, 3, 4, 5],
[Symbol.iterator]: function* () {
for (let item of this.items) {
yield item;
}
}
};
for (let item of myCollection) {
console.log(item); // Izvade: 1, 2, 3, 4, 5
}
console.log([...myCollection]); // Izvade: [1, 2, 3, 4, 5]
Šajā piemērā myCollection
ir objekts, kas ievieš iteratora protokolu, izmantojot Symbol.iterator
. Ģeneratora funkcija atgriež katru elementu items
masīvā, padarot myCollection
iterējamu.
Symbol.toStringTag
Symbol.toStringTag
ir simbols, kas ļauj pielāgot objekta virknes attēlojumu, kad tiek izsaukts Object.prototype.toString()
.
Piemērs: toString() attēlojuma pielāgošana
class MyClass {
get [Symbol.toStringTag]() {
return 'MyClassInstance';
}
}
const instance = new MyClass();
console.log(Object.prototype.toString.call(instance)); // Izvade: [object MyClassInstance]
Bez Symbol.toStringTag
izvade būtu [object Object]
. Šis simbols nodrošina veidu, kā sniegt aprakstošāku virknes attēlojumu jūsu objektiem.
Symbol.hasInstance
Symbol.hasInstance
ir simbols, kas ļauj pielāgot operatora instanceof
uzvedību. Parasti instanceof
pārbauda, vai objekta prototipu ķēde satur konstruktora prototype
īpašību. Symbol.hasInstance
ļauj jums pārrakstīt šo uzvedību.
Piemērs: instanceof pārbaudes pielāgošana
class MyClass {
static [Symbol.hasInstance](instance) {
return Array.isArray(instance);
}
}
console.log([] instanceof MyClass); // Izvade: true
console.log({} instanceof MyClass); // Izvade: false
Šajā piemērā Symbol.hasInstance
metode pārbauda, vai instance ir masīvs. Tas efektīvi padara MyClass
par pārbaudi masīviem, neatkarīgi no faktiskās prototipu ķēdes.
Citi labi zināmie simboli
JavaScript definē vairākus citus labi zināmus simbolus, tostarp:
Symbol.toPrimitive
: Ļauj pielāgot objekta uzvedību, kad tas tiek pārvērsts par primitīvu vērtību (piemēram, aritmētisko operāciju laikā).Symbol.unscopables
: Norāda īpašību nosaukumus, kas jāizslēdz nowith
priekšrakstiem (with
lietošana parasti nav ieteicama).Symbol.match
,Symbol.replace
,Symbol.search
,Symbol.split
: Ļauj pielāgot, kā objekti uzvedas ar regulāro izteiksmju metodēm, piemēram,String.prototype.match()
,String.prototype.replace()
utt.
Globālais simbolu reģistrs
Dažreiz ir nepieciešams koplietot simbolus starp dažādām lietojumprogrammas daļām vai pat starp dažādām lietojumprogrammām. Globālais simbolu reģistrs nodrošina mehānismu simbolu reģistrēšanai un izgūšanai pēc atslēgas.
Symbol.for(atslēga)
Metode Symbol.for(key)
pārbauda, vai globālajā reģistrā pastāv simbols ar norādīto atslēgu. Ja tas pastāv, tā atgriež šo simbolu. Ja tas nepastāv, tā izveido jaunu simbolu ar šo atslēgu un reģistrē to reģistrā.
const globalSymbol1 = Symbol.for("myGlobalSymbol");
const globalSymbol2 = Symbol.for("myGlobalSymbol");
console.log(globalSymbol1 === globalSymbol2); // Izvade: true
console.log(Symbol.keyFor(globalSymbol1)); // Izvade: myGlobalSymbol
Symbol.keyFor(simbols)
Metode Symbol.keyFor(symbol)
atgriež atslēgu, kas saistīta ar simbolu globālajā reģistrā. Ja simbols nav reģistrā, tā atgriež undefined
.
const mySymbol = Symbol("localSymbol");
console.log(Symbol.keyFor(mySymbol)); // Izvade: undefined
const globalSymbol = Symbol.for("myGlobalSymbol");
console.log(Symbol.keyFor(globalSymbol)); // Izvade: myGlobalSymbol
Svarīgi: Simboli, kas izveidoti ar Symbol()
, *netiek* automātiski reģistrēti globālajā reģistrā. Tikai simboli, kas izveidoti (vai izgūti) ar Symbol.for()
, ir daļa no reģistra.
Praktiski piemēri un pielietojuma gadījumi
Šeit ir daži praktiski piemēri, kas demonstrē, kā simbolus var izmantot reālās situācijās:
1. Spraudņu sistēmu izveide
Simbolus var izmantot, lai izveidotu spraudņu sistēmas, kur dažādi moduļi var paplašināt galvenā objekta funkcionalitāti, nekonfliktējot ar citiem moduļiem.
// Galvenais objekts
const coreObject = {
name: "Galvenais Objekts",
version: "1.0"
};
// 1. spraudnis
const plugin1Key = Symbol("plugin1");
coreObject[plugin1Key] = {
description: "1. spraudnis pievieno papildu funkcionalitāti",
activate: function() {
console.log("1. spraudnis aktivizēts");
}
};
// 2. spraudnis
const plugin2Key = Symbol("plugin2");
coreObject[plugin2Key] = {
author: "Cits Izstrādātājs",
init: function() {
console.log("2. spraudnis inicializēts");
}
};
// Piekļuve spraudņiem
console.log(coreObject[plugin1Key].description); // Izvade: 1. spraudnis pievieno papildu funkcionalitāti
coreObject[plugin2Key].init(); // Izvade: 2. spraudnis inicializēts
Šajā piemērā katrs spraudnis izmanto unikālu simbola atslēgu, novēršot potenciālos nosaukumu konfliktus un nodrošinot, ka spraudņi var mierīgi līdzāspastāvēt.
2. Metadatu pievienošana DOM elementiem
Simbolus var izmantot, lai pievienotu metadatus DOM elementiem, netraucējot to esošajiem atribūtiem vai īpašībām.
const element = document.createElement("div");
const dataKey = Symbol("elementData");
element[dataKey] = {
type: "widget",
config: {},
timestamp: Date.now()
};
// Piekļuve metadatiem
console.log(element[dataKey].type); // Izvade: widget
Šī pieeja uztur metadatus atsevišķi no elementa standarta atribūtiem, uzlabojot uzturamību un izvairoties no potenciāliem konfliktiem ar CSS vai citu JavaScript kodu.
3. Privāto īpašību ieviešana
Lai gan JavaScript nav patiesi privātu īpašību, simbolus var izmantot, lai simulētu privātumu. Izmantojot simbolu kā īpašības atslēgu, jūs varat apgrūtināt (bet ne padarīt neiespējamu) ārējam kodam piekļuvi šai īpašībai.
class MyClass {
#privateSymbol = Symbol("privateData"); // Piezīme: Šī '#' sintakse ir *īsts* privāts lauks, ieviests ES2020, atšķirīgs no piemēra
constructor(data) {
this[this.#privateSymbol] = data;
}
getData() {
return this[this.#privateSymbol];
}
}
const myInstance = new MyClass("Sensitīva Informācija");
console.log(myInstance.getData()); // Izvade: Sensitīva Informācija
// Piekļuve "privātajai" īpašībai (sarežģīti, bet iespējami)
const symbolKeys = Object.getOwnPropertySymbols(myInstance);
console.log(myInstance[symbolKeys[0]]); // Izvade: Sensitīva Informācija
Lai gan Object.getOwnPropertySymbols()
joprojām var atklāt simbolu, tas samazina iespēju, ka ārējais kods nejauši piekļūs vai modificēs "privāto" īpašību. Piezīme: Mūsdienu JavaScript ir pieejami patiesi privātie lauki (izmantojot `#` prefiksu), kas piedāvā spēcīgākas privātuma garantijas.
Labākās prakses simbolu lietošanā
Šeit ir dažas labākās prakses, kas jāpatur prātā, strādājot ar simboliem:
- Izmantojiet aprakstošus simbolu aprakstus: Jēgpilnu aprakstu sniegšana atvieglo atkļūdošanu un reģistrēšanu.
- Apsveriet globālo simbolu reģistru: Izmantojiet
Symbol.for()
, ja nepieciešams koplietot simbolus starp dažādiem moduļiem vai lietojumprogrammām. - Pievērsiet uzmanību uzskaitīšanai: Atcerieties, ka simbolu īpašības pēc noklusējuma nav uzskaitāmas, un izmantojiet
Object.getOwnPropertySymbols()
, lai tām piekļūtu. - Izmantojiet simbolus metadatiem: Izmantojiet simbolu priekšrocības, lai pievienotu metadatus objektiem, netraucējot to esošajām īpašībām.
- Apsveriet patiesus privātos laukus, ja nepieciešams spēcīgs privātums: Ja jums ir nepieciešams īsts privātums, izmantojiet `#` prefiksu privātiem klases laukiem (pieejams mūsdienu JavaScript).
Noslēgums
JavaScript simboli piedāvā jaudīgu mehānismu unikālu īpašību atslēgu izveidei, metadatu pievienošanai objektiem un objektu uzvedības pielāgošanai. Izprotot, kā darbojas simboli, un ievērojot labākās prakses, jūs varat rakstīt stabilāku, uzturamāku un bezkonfliktu JavaScript kodu. Neatkarīgi no tā, vai jūs veidojat spraudņu sistēmas, pievienojat metadatus DOM elementiem vai simulējat privātas īpašības, simboli nodrošina vērtīgu rīku jūsu JavaScript izstrādes darba plūsmas uzlabošanai.