(inleiding/introspectie.js) in het bovenstaande programma hebben we typeof
en instanceof
operators gebruikt in de coerce
functie om het gegevenstype van inkomende . Dit is de basis demonstratie van introspectie. Echter, een taal die specifiek is ontworpen voor metaprogrammering kan een aantal krachtige introspectie tools bieden.
u kunt de operator in
gebruiken om te controleren of er een eigenschap in het object bestaat. De Globale functie isNaN
controleert of het object NaN
is. Er zijn enkele statische methoden gebouwd rond het Object
om waarden van het Object
te inspecteren, zoals Object.isFrozen(value)
om te controleren of value
bevroren is of Object.keys(value)
om de eigenschapsnamen van het value
object.
tot ES5 hadden we deze operators en deze methoden om mee te werken. In ES2015 (ES6) introduceerde JavaScript Reflect
object dat een aantal statische methoden biedt (net als Object
) maar specifiek ontworpen voor introspectie. Omdat we een aparte les hebben over Reflect
, worden deze methoden hier besproken.
Intercessie
Intercessie is het proces van ingrijpen in de JavaScript-processen en het aanpassen van het standaardgedrag van het proces. JavaScript biedt geweldige tools voor voorbede, waaronder Proxy
.
De Proxy
klasse werd geà ntroduceerd in ES2015 (ES6) om basis JavaScript operaties rond objecten te onderscheppen (tussen te komen), net zoals we hierboven hebben gezien, maar op een veel mooiere manier. We hebben een aparte les over Proxy
(binnenkort beschikbaar) maar in een notendop, Proxy
wikkelt een onderscheppende logica rond een object.
var targetWithProxy = new Proxy(target, handler);
Hier is de target
object en handler
de interceptor. De handler
is ook een gewoon JavaScript-object, maar met enkele betekenisvolle velden. For example, handler.get
would be a function that returns a custom value when target.prop
(here, prop
is any property) is accessed.
(introduction/proxy.js)
Proxy is a great way to provide abstractions over your not-so-public data. In het bovenstaande programma hebben we bijvoorbeeld abstracties gegeven over target
object en hebben we aangepast hoe het zichzelf aan het publiek moet presenteren.
enige voorspraak was mogelijk in ES5, zoals het gebruik van getter
en setters
op property descriptors, maar het zou resulteren in de mutatie van het target
object. Proxy
biedt een veel schonere manier om voorbede te bereiken zonder het oorspronkelijke object te hoeven wijzigen (target
).
modificatie
modificatie verwijst naar de modificatie van het gedrag van het programma door middel van mutatie. In het geval van voorspraak onderschepten we alleen de standaard JavaScript-processen door een onderscheppende logica toe te voegen tussen het doel en de ontvanger zonder het doel te schaden. In dit geval wijzigen we het gedrag van het doel zelf zodat het past bij de ontvanger.
het overschrijven van een functieimplementatie zou een goed voorbeeld van wijziging zijn. Bijvoorbeeld, als een functie is ontworpen om zich op een bepaalde manier te gedragen, maar we willen iets anders voorwaardelijk, kunnen we dat doen door een zelfoverheersende functie te ontwerpen. Laat een voorbeeld zien.
(introduction/function-modification.js)
in het bovenstaande voorbeeld hebben we een functie gemaakt die zichzelf overschrijft met een nieuwe functie-implementatie. Dit zou het hardste voorbeeld van modificatie zijn, maar we hebben andere, misschien zinvollere use cases.
(introduction/readonly-object.js) in het bovenstaande voorbeeld hebben we Object.defineProperty()
methode gebruikt om de standaard eigenschap descriptor van de name
eigenschap te wijzigen om het alleen-lezen te maken. U kunt ook deObject.freeze()
methode gebruiken om het gehele object te vergrendelen om mutaties te voorkomen.
sommige voorbeden kunnen plaatsvinden door middel van wijzigingen zoals u kunt uit het bovenstaande voorbeeld. Door het instellen van writable:false
in de eigenschap descriptor van het object, dus muteren van het object (interne implementatie), hebben we de waarde toewijzing operatie.
Als u niet bekend bent met de valueOf
methode, wordt deze gebruikt om een object te dwingen tot een primitieve waarde. Dus als ik een object heb en het heeft valueOf
methode op zichzelf of op zijn prototype keten, dan wordt deze methode aangeroepen door JavaScript wanneer je probeert een rekenkundige bewerking op het uit te voeren. Standaard heeft Object
de methode valueOf
die zichzelf (het object) retourneert.
(introduction/value of.js) zoals u in het bovenstaande voorbeeld kunt zien, resulteerde emp1/10
in een NaN
omdat een object niet kan worden verdeeld als natuurlijke getallen. Maar later hebben we valueOf
methode toegevoegd aan Employee
klasse die salary
waarde van het object retourneert. Daarom gaf emp2/10
200
omdat emp2.salary
is 200
. Evenzo gaf emp3/10
300
zoals we valueOf
methode direct op de emp3
hebben toegevoegd.
dus bij elke stap in het bovenstaande voorbeeld interveniëren we hoe een object wordt gepresenteerd aan een standaard JavaScript-operatie en veranderen we zijn gedrag naar onze voorkeuren. Dit is niets anders dan voorspraak.
in ES2015 (ES6) heeft JavaScript een nieuw primitief gegevenstype geïntroduceerd dat symbol
is. Het is niets zoals we eerder hebben gezien en kan niet worden weergegeven in letterlijke vorm. Het kan alleen geconstrueerd worden door de functie Symbol
aan te roepen.
var sym1 = Symbol(); var sym2 = Symbol(); var sym3 = Symbol('description'); // description for debugging aidsym1 === sym2 // false sym1 === sym2 // falsetypeof sym1 // 'symbol'console.log( sym1 ); // 'Symbol()' console.log( sym3 ); // 'Symbol(description)'
In een notendop produceert het unieke waarden die ook kunnen worden gebruikt als reguliere objecttoetsen met behulp van de obj
notatie waarbij key
een symbool zou zijn.
var key = Symbol();var obj = { name: 'Ross', : 200 };console.log( obj.name ); // 'Ross' console.log( obj ); // 200 Object.keys(obj); // obj = 300;
omdat ze uniek zijn, is er geen manier om per ongeluk een duplicaat te maken. Elk nieuw symbool is uniek (aangemaakt met Symbol()
) wat betekent dat als u hetzelfde symbool wilt gebruiken, u dat in een variabele moet opslaan en die variabele moet doorgeven om naar hetzelfde symbool te verwijzen.
in het voorbeeld valueOf
kunt u het probleem herkennen als we niet voorzichtig of bewust zijn. Aangezien valueOf
eenstring
eigenschap is (zoals in emp3
), kan iedereen het per ongeluk overschrijven of iemand die niet op de hoogte is van valueOf
zou het voor eigen gebruik kunnen gebruiken denkend ” wat zit er in de naam?”.
omdat symbolen ook als objectsleutels kunnen worden gebruikt, heeft JavaScript een aantal globale symbolen verstrekt die gebruikt zouden moeten worden als objectsleutels voor sommige standaard JavaScript-bewerkingen. Omdat deze symbolen bekend zijn bij een ontwikkelaar, worden ze “bekende symbolen”genoemd. Deze bekende symbolen worden aan het publiek blootgesteld als de statische eigenschappen van de functie Symbol
.
een van de bekende symbolen is Symbol.toPrimitive
die gebruikt moet worden als de sleutel van het object om zijn primitieve waarde te verkrijgen. Ja, je denkt goed, het is een vervanging van valueOf
methode en het heeft de voorkeur.
(introduction/symbol-toPrimitive.js)
💡 de methode toPrimitive
doet meer dan alleen een getalwaarde van het object retourneren. Lees de symbolen lessen om er meer over te weten.
JavaScript biedt veel van dergelijke bekende symbolen om het standaard JavaScript-gedrag rond objecten te onderscheppen en te wijzigen. We zullen hierover praten en symbolen in het algemeen in de symbolen les.