Avastage JavaScripti sümbolid: nende eesmärk, loomine, kasutamine unikaalsete võtmete ja metaandmete jaoks ning nimekonfliktide vältimine. Praktilised näited.
JavaScripti sümbolid: unikaalsed omaduste võtmed ja metaandmed
JavaScripti sümbolid, mis võeti kasutusele ECMAScript 2015-s (ES6), pakuvad mehhanismi unikaalsete ja muutumatute omaduste võtmete loomiseks. Erinevalt stringidest või numbritest on sümbolid garanteeritult unikaalsed kogu teie JavaScripti rakenduses. Need pakuvad viisi nimekonfliktide vältimiseks, metaandmete lisamiseks objektidele olemasolevaid omadusi segamata ja objektide käitumise kohandamiseks. See artikkel annab põhjaliku ülevaate JavaScripti sümbolitest, hõlmates nende loomist, rakendusi ja parimaid tavasid.
Mis on JavaScripti sümbolid?
Sümbol on primitiivne andmetüüp JavaScriptis, sarnaselt numbrite, stringide, tõeväärtuste, nulli ja undefined-iga. Kuid erinevalt teistest primitiivsetest tüüpidest on sümbolid unikaalsed. Iga kord, kui loote sümboli, saate täiesti uue, unikaalse väärtuse. See unikaalsus muudab sümbolid ideaalseks:
- Unikaalsete omaduste võtmete loomine: Sümbolite kasutamine omaduste võtmetena tagab, et teie omadused ei satu konflikti olemasolevate omadustega või teiste teekide või moodulite lisatud omadustega.
- Metaandmete talletamine: Sümboleid saab kasutada metaandmete lisamiseks objektidele viisil, mis on peidetud standardsete loendusmeetodite eest, säilitades objekti terviklikkuse.
- Objekti käitumise kohandamine: JavaScript pakub komplekti tuntud sümboleid, mis võimaldavad teil kohandada, kuidas objektid teatud olukordades käituvad, näiteks itereerimisel või stringiks teisendamisel.
Sümbolite loomine
Sümboli loomiseks kasutatakse konstruktorit Symbol()
. On oluline märkida, et te ei saa kasutada new Symbol()
; sümbolid ei ole objektid, vaid primitiivsed väärtused.
Sümboli põhiline loomine
Lihtsaim viis sümboli loomiseks on:
const mySymbol = Symbol();
console.log(typeof mySymbol); // Väljund: symbol
Iga Symbol()
väljakutse genereerib uue, unikaalse väärtuse:
const symbol1 = Symbol();
const symbol2 = Symbol();
console.log(symbol1 === symbol2); // Väljund: false
Sümbolite kirjeldused
Sümboli loomisel saate anda valikulise string-kirjelduse. See kirjeldus on kasulik silumiseks ja logimiseks, kuid see ei mõjuta sümboli unikaalsust.
const mySymbol = Symbol("myDescription");
console.log(mySymbol.toString()); // Väljund: Symbol(myDescription)
Kirjeldus on puhtalt informatiivne; kaks sama kirjeldusega sümbolit on siiski unikaalsed:
const symbolA = Symbol("same description");
const symbolB = Symbol("same description");
console.log(symbolA === symbolB); // Väljund: false
Sümbolite kasutamine omaduste võtmetena
Sümbolid on eriti kasulikud omaduste võtmetena, kuna need tagavad unikaalsuse, vältides nimekonflikte objektidele omaduste lisamisel.
Sümbol-omaduste lisamine
Sümboleid saab kasutada omaduste võtmetena täpselt nagu stringe või numbreid:
const mySymbol = Symbol("myKey");
const myObject = {};
myObject[mySymbol] = "Hello, Symbol!";
console.log(myObject[mySymbol]); // Väljund: Hello, Symbol!
Nimekonfliktide vältimine
Kujutage ette, et töötate kolmanda osapoole teegiga, mis lisab objektidele omadusi. Võiksite lisada oma omadusi, riskimata olemasolevate ülekirjutamisega. Sümbolid pakuvad selleks turvalise viisi:
// Kolmanda osapoole teek (simuleeritud)
const libraryObject = {
name: "Library Object",
version: "1.0"
};
// Teie kood
const mySecretKey = Symbol("mySecret");
libraryObject[mySecretKey] = "Top Secret Information";
console.log(libraryObject.name); // Väljund: Library Object
console.log(libraryObject[mySecretKey]); // Väljund: Top Secret Information
Selles näites tagab mySecretKey
, et teie omadus ei satu konflikti ühegi olemasoleva omadusega objektis libraryObject
.
Sümbol-omaduste loendamine
Üks sümbol-omaduste oluline omadus on see, et need on peidetud standardsete loendusmeetodite, nagu for...in
tsüklid ja Object.keys()
, eest. See aitab kaitsta objektide terviklikkust ja vältida sümbol-omaduste juhuslikku kasutamist või muutmist.
const mySymbol = Symbol("myKey");
const myObject = {
name: "My Object",
[mySymbol]: "Symbol Value"
};
console.log(Object.keys(myObject)); // Väljund: ["name"]
for (let key in myObject) {
console.log(key); // Väljund: name
}
Sümbol-omadustele juurdepääsemiseks peate kasutama meetodit Object.getOwnPropertySymbols()
, mis tagastab massiivi kõigist objekti sümbol-omadustest:
const mySymbol = Symbol("myKey");
const myObject = {
name: "My Object",
[mySymbol]: "Symbol Value"
};
const symbolKeys = Object.getOwnPropertySymbols(myObject);
console.log(symbolKeys); // Väljund: [Symbol(myKey)]
console.log(myObject[symbolKeys[0]]); // Väljund: Symbol Value
Tuntud sümbolid
JavaScript pakub komplekti sisseehitatud sümboleid, mida tuntakse tuntud sümbolitena ja mis esindavad spetsiifilisi käitumisviise või funktsionaalsusi. Need sümbolid on Symbol
konstruktori omadused (nt Symbol.iterator
, Symbol.toStringTag
). Need võimaldavad teil kohandada, kuidas objektid erinevates kontekstides käituvad.
Symbol.iterator
Symbol.iterator
on sümbol, mis defineerib objekti vaikeiteraatori. Kui objektil on meetod võtmega Symbol.iterator
, muutub see itereeritavaks, mis tähendab, et saate seda kasutada for...of
tsüklite ja laialilaotusoperaatoriga (...
).
Näide: kohandatud itereeritava objekti loomine
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); // Väljund: 1, 2, 3, 4, 5
}
console.log([...myCollection]); // Väljund: [1, 2, 3, 4, 5]
Selles näites on myCollection
objekt, mis rakendab iteraatori protokolli, kasutades Symbol.iterator
. Generaatorfunktsioon väljastab (yield) iga elemendi items
massiivist, muutes myCollection
objekti itereeritavaks.
Symbol.toStringTag
Symbol.toStringTag
on sümbol, mis võimaldab teil kohandada objekti string-esitust, kui kutsutakse välja Object.prototype.toString()
.
Näide: toString() esituse kohandamine
class MyClass {
get [Symbol.toStringTag]() {
return 'MyClassInstance';
}
}
const instance = new MyClass();
console.log(Object.prototype.toString.call(instance)); // Väljund: [object MyClassInstance]
Ilma Symbol.toStringTag
-ita oleks väljund [object Object]
. See sümbol pakub viisi oma objektidele kirjeldavama string-esituse andmiseks.
Symbol.hasInstance
Symbol.hasInstance
on sümbol, mis laseb teil kohandada operaatori instanceof
käitumist. Tavaliselt kontrollib instanceof
, kas objekti prototüübiahel sisaldab konstruktori prototype
omadust. Symbol.hasInstance
võimaldab seda käitumist üle kirjutada.
Näide: instanceof kontrolli kohandamine
class MyClass {
static [Symbol.hasInstance](instance) {
return Array.isArray(instance);
}
}
console.log([] instanceof MyClass); // Väljund: true
console.log({} instanceof MyClass); // Väljund: false
Selles näites kontrollib Symbol.hasInstance
meetod, kas isend on massiiv. See muudab MyClass
-i tegelikult massiivide kontrollijaks, sõltumata tegelikust prototüübiahelast.
Muud tuntud sümbolid
JavaScript defineerib mitmeid teisi tuntud sümboleid, sealhulgas:
Symbol.toPrimitive
: Võimaldab teil kohandada objekti käitumist, kui see teisendatakse primitiivseks väärtuseks (nt aritmeetiliste tehete ajal).Symbol.unscopables
: Määrab omaduste nimed, mis tulekswith
-lausetest välja jätta (with
-i kasutamine on üldiselt ebasoovitatav).Symbol.match
,Symbol.replace
,Symbol.search
,Symbol.split
: Võimaldavad teil kohandada, kuidas objektid käituvad regulaaravaldise meetoditega naguString.prototype.match()
,String.prototype.replace()
jne.
Globaalne sümbolite register
Mõnikord on vaja sümboleid jagada rakenduse erinevate osade vahel või isegi erinevate rakenduste vahel. Globaalne sümbolite register pakub mehhanismi sümbolite registreerimiseks ja hankimiseks võtme alusel.
Symbol.for(key)
Meetod Symbol.for(key)
kontrollib, kas antud võtmega sümbol eksisteerib globaalses registris. Kui see eksisteerib, tagastab see selle sümboli. Kui seda ei eksisteeri, loob see uue sümboli antud võtmega ja registreerib selle registris.
const globalSymbol1 = Symbol.for("myGlobalSymbol");
const globalSymbol2 = Symbol.for("myGlobalSymbol");
console.log(globalSymbol1 === globalSymbol2); // Väljund: true
console.log(Symbol.keyFor(globalSymbol1)); // Väljund: myGlobalSymbol
Symbol.keyFor(symbol)
Meetod Symbol.keyFor(symbol)
tagastab võtme, mis on seotud sümboliga globaalses registris. Kui sümbolit registris ei ole, tagastab see undefined
.
const mySymbol = Symbol("localSymbol");
console.log(Symbol.keyFor(mySymbol)); // Väljund: undefined
const globalSymbol = Symbol.for("myGlobalSymbol");
console.log(Symbol.keyFor(globalSymbol)); // Väljund: myGlobalSymbol
Oluline: Sümbolid, mis on loodud Symbol()
abil, *ei ole* automaatselt globaalsesse registrisse registreeritud. Ainult sümbolid, mis on loodud (või hangitud) Symbol.for()
abil, on registri osa.
Praktilised näited ja kasutusjuhud
Siin on mõned praktilised näited, mis demonstreerivad, kuidas sümboleid saab kasutada reaalsetes stsenaariumides:
1. Plugin-süsteemide loomine
Sümboleid saab kasutada plugin-süsteemide loomiseks, kus erinevad moodulid saavad laiendada põhilise objekti funktsionaalsust, ilma et nad satuksid konflikti üksteise omadustega.
// Põhiobjekt
const coreObject = {
name: "Core Object",
version: "1.0"
};
// Plugin 1
const plugin1Key = Symbol("plugin1");
coreObject[plugin1Key] = {
description: "Plugin 1 adds extra functionality",
activate: function() {
console.log("Plugin 1 activated");
}
};
// Plugin 2
const plugin2Key = Symbol("plugin2");
coreObject[plugin2Key] = {
author: "Another Developer",
init: function() {
console.log("Plugin 2 initialized");
}
};
// Pluginitele juurdepääs
console.log(coreObject[plugin1Key].description); // Väljund: Plugin 1 adds extra functionality
coreObject[plugin2Key].init(); // Väljund: Plugin 2 initialized
Selles näites kasutab iga plugin unikaalset sümboli võtit, vältides potentsiaalseid nimekonflikte ja tagades, et pluginad saavad rahulikult koos eksisteerida.
2. Metaandmete lisamine DOM-elementidele
Sümboleid saab kasutada metaandmete lisamiseks DOM-elementidele, segamata nende olemasolevaid atribuute või omadusi.
const element = document.createElement("div");
const dataKey = Symbol("elementData");
element[dataKey] = {
type: "widget",
config: {},
timestamp: Date.now()
};
// Metaandmetele juurdepääs
console.log(element[dataKey].type); // Väljund: widget
See lähenemine hoiab metaandmed eraldi elemendi standardatribuutidest, parandades hooldatavust ja vältides potentsiaalseid konflikte CSS-i või muu JavaScripti koodiga.
3. Privaatsete omaduste implementeerimine
Kuigi JavaScriptil pole tõelisi privaatseid omadusi, saab sümboleid kasutada privaatsuse simuleerimiseks. Kasutades sümbolit omaduse võtmena, saate muuta välise koodi jaoks omadusele juurdepääsu raskeks (kuid mitte võimatuks).
class MyClass {
#privateSymbol = Symbol("privateData"); // Märkus: See '#' süntaks on *tõeline* privaatne väli, mis võeti kasutusele ES2020-s, ja erineb näitest
constructor(data) {
this[this.#privateSymbol] = data;
}
getData() {
return this[this.#privateSymbol];
}
}
const myInstance = new MyClass("Sensitive Information");
console.log(myInstance.getData()); // Väljund: Sensitive Information
// "Privaatsele" omadusele juurdepääs (raske, kuid võimalik)
const symbolKeys = Object.getOwnPropertySymbols(myInstance);
console.log(myInstance[symbolKeys[0]]); // Väljund: Sensitive Information
Kuigi Object.getOwnPropertySymbols()
saab sümboli siiski paljastada, muudab see vähem tõenäoliseks, et väline kood pääseb juhuslikult "privaatsele" omadusele ligi või muudab seda. Märkus: Tõelised privaatsed väljad (kasutades `#` prefiksit) on nüüd saadaval kaasaegses JavaScriptis ja pakuvad tugevamaid privaatsusgarantiisid.
Parimad tavad sümbolite kasutamisel
Siin on mõned parimad tavad, mida sümbolitega töötades meeles pidada:
- Kasutage kirjeldavaid sümbolite kirjeldusi: Mõtestatud kirjelduste pakkumine muudab silumise ja logimise lihtsamaks.
- Kaaluge globaalse sümbolite registri kasutamist: Kasutage
Symbol.for()
, kui peate sümboleid jagama erinevate moodulite või rakenduste vahel. - Olge teadlik loendamisest: Pidage meeles, et sümbol-omadused ei ole vaikimisi loendatavad ja kasutage nendele juurdepääsuks
Object.getOwnPropertySymbols()
. - Kasutage sümboleid metaandmete jaoks: Kasutage sümboleid metaandmete lisamiseks objektidele, segamata nende olemasolevaid omadusi.
- Kaaluge tõelisi privaatseid välju, kui on vaja tugevat privaatsust: Kui vajate tõelist privaatsust, kasutage klassi privaatsete väljade jaoks `#` prefiksit (saadaval kaasaegses JavaScriptis).
Kokkuvõte
JavaScripti sümbolid pakuvad võimsat mehhanismi unikaalsete omaduste võtmete loomiseks, metaandmete lisamiseks objektidele ja objektide käitumise kohandamiseks. Mõistes, kuidas sümbolid töötavad ja järgides parimaid tavasid, saate kirjutada robustsemat, hooldatavamat ja konfliktivaba JavaScripti koodi. Olgu tegemist plugin-süsteemide ehitamise, metaandmete lisamisega DOM-elementidele või privaatsete omaduste simuleerimisega, sümbolid on väärtuslik tööriist teie JavaScripti arendustöövoo täiustamiseks.