Categorie
Javascript Programmazione

{JS} Reflect

Cos’è la Riflessione?

In informatica, la reflective programming o reflection è la capacità di esaminare, introspezionare e modificare la struttura e il proprio comportamento.
Come diversi linguaggi di programmazione, anche JavaScript supporta la reflection, cioè la capacità di analizzare e modificare a runtime (in corso di esecuzione) la struttura degli elementi e dei dati di un programma.

L’oggetto Reflect

Reflect è un oggetto integrato, globale. 
Reflect non è un costruttore, non puoi quindi usarlo con un new operatore e non crea di conseguenza istanze.
Tutte le proprietà e i metodi di Reflect sono statici, proprio come l’ oggetto Math.

Note: Molti dei metodi qui sotto elencati sono similari a metodi già presenti in Object; i quali, seppur similari, restituiscono valori differenti.

Metodi

Reflect.has(oggetto, “proprietà”)verifica l’esistenza di una proprietà all’interno di un oggetto risalendo la catena dei prototipi;restituisce true/false
Reflect.hasOwnProperty(oggetto, “proprietà”)verifica l’esistenza di una proprietà all’interno di un oggetto; restituisce true/false
Reflect.ownKeys(oggetto)restituisce un array in stringhe di tutte le proprietà dell’oggettorestituisce array di stringhe
Reflect.defineProperty(oggetto, “proprieta”, { descrittori })modifica una proprietà esistente  di uno oggetto e aggiunge i data-descriptorrestituisce true/false
Reflect.get(oggetto, “proprietà”)ricava il valore della proprietà di un oggettorestituisce il valore della proprietà
Reflect.set(oggetto, “proprietà”)aggiorna il valore di una proprietà di un oggettorestituisce true/false
Reflect.deleteProperty(oggetto, “proprietà”)elimina una proprietà esistente di un oggettorestituisce true/false
Reflect.getPrototypeOf(oggetto)restituisce il prototipo di un oggettorestituisce l’oggetto prototipo se presente altrimenti valore null
Reflect.setPrototypeOf(oggetto, oggetto)consente di assegnare un prototipo ad un oggettorestituisce true/false
Reflect.preventExtensions(oggetto) impedisce l’estensibilità di un oggetto, cioè la possibilità di aggiungere nuove proprietàrestituisce true/false
Reflect.isExtensible(oggetto)verificare se un oggetto è estensibilerestituisce true/false
Reflect.apply(funzione, this, [array parametri])consente di invocare una funzione specificando la funzione, il valore di this e i paramenti da passarerestituisce il valore della funzione invocata
Reflect.construct(costruttore, argomenti, prototipo)consente di invocare un costruttore, l’insieme di argomenti da passare ed un prototipo differente (opzionale)restituisce istanza del costruttore
Oggetto
var persona = {
nome: "Mario",
cognome: "Rossi",
email: "mario.rossi@email.it"
}

Reflect.has()

Reflect.has(oggetto, "proprietà")

Verifica l’esistenza di una proprietà all’interno di un oggetto risalendo la catena dei prototipi. Restituisce true/false.

var proprietaEmailEsiste = Reflect.has(persona, "email");
// Risultato true
Reflect.hasOwnProperty()
Reflect.hasOwnProperty(oggetto, "proprietà")

Come il metodo precedente ma non estendere la ricerca lungo la catena dei prototipi. Restituisce true/false.

Reflect.ownKeys()

Reflect.ownKeys(oggetto)

Il metodo ownKeys() restituisce un array in stringhe di tutte le proprietà dell’oggetto, non ereditate.

var tutteLeProprita = Reflect.ownKeys(persona);
// Risultato ["nome","cognome","email"]

Reflect.defineProperty()

Reflect.defineProperty(oggetto, "proprieta", { descrittori })

La metodo defineProperty() aggiunge o modifica una proprietà esistente  di uno oggetto ed aggiunge i data-descriptor.

Modifica proprietà e aggiunta Data-descriptor
Reflect.defineProperty(persona, "nome", { 
value: "Mario",
writable: true,
configurable: true,
enumerable: true
});
Note: Reflect.defineProperty() accetta solo i data-descriptor;
La similare proprietà Object.defineProperty() accetta invece sia i data-descriptor sia gli accessor-descriptor.

Reflect.get()

Reflect.get(oggetto, "proprieta");

Il metodo Reflect.get() prende e restituisce il valore della proprietà.

Reflect.get(persona, "nome");

Reflect.set()

Reflect.set(oggetto, "proprieta", value);

Il metodo Reflect.set() aggiorna, non crea (per questo abbiamo Reflect.defineProperty(), che d’altro canto si occupa anch”esso della creazione), il valore di una proprietà di un oggetto.

Reflect.set(persona, "nome", "Mario");
Note:Reflect.get() e Reflect.set() prevedono un ulteriore parametro opzionale:

Reflect.get(ObjectTarget, propertyKey, ObjectReceiver);

Se utilizzato con Proxy, può essere un oggetto, ObjectReceiver, che eredita da ObjectRiceiver.

Reflect.deleteProperty()

Reflect.deleteProperty(oggetto, "proprieta");

Il metodo Reflect.deleteProperty() consente di eliminare una proprietà esistente di un oggetto.

Reflect.deleteProperty(persona, "nome");

Reflect.getPrototypeOf()

Reflect.deleteProperty(oggetto);

Il metodo Reflect.getPrototypeOf() restituisce l’oggetto prototipo dell’oggetto indicato come parametro. Se non impostare restituisce valore “null”.

Reflect.deleteProperty(persona);
// Risultato Object

Reflect.setPrototypeOf()

Reflect.setPrototypeOf(oggetto, oggettoPrototipo);

Il metodo Reflect.setPrototypeOf() imposta l’oggetto da impostare come prototipo di un altro oggetto.

Reflect.setPrototypeOf(persona, Istruttore);

Reflect.preventExtensions()

Reflect.preventExtensions(oggetto);

Il metodo Reflect.preventExtensions() impedisce l’estensibilità di un oggetto, cioè la possibilità di aggiungere nuove proprietà.

Reflect.isExtensible()

Reflect.isExtensible(oggetto);

Il metodo Reflect.isExtensible() verifica l’estensibilità di un oggetto, cioè la possibilità di aggiungere proprietà.

Reflect.apply()

Reflect.apply(funzione, this, [array parametri]);

Il metodo Reflect.apply() consente di invocare una funzione specificando un determinato valore per this e i valori da passare in formato array.

Funzione semplice
var valore = 10;
function sommaExtra(x, y) {
    return this + x + y;
 }
Reflect.apply(sommaExtra, valore, [10,20]);
Funzione di callback
var persona = {
 nome: "Mario",
 cognome: "Rossi",
 mostraNomeCompleto: function(value) {
  return this.nome + " " + this.cognome + value;
 }
};

function saluta(callback) {
return "Buongiorno " + callback ;
}

document.write(saluta(Reflect.apply(persona.mostraNomeCompleto, persona, [" lieto di vederti"])));

Reflect.construct()

Reflect.construct(costruttore, [argomenti], prototipo)

Il seguente metodo consente di invocare un costruttore, l’insieme di argomenti da passare ad esso ed eventualmente prototipo diffrerente (opzionale).
Agisce come "new Costruttore” ma da  anche l’opzione aggiuntiva per specificare un prototipo diverso.

Costruttore principale

Semplice costruttore di persone

function Persona(nome, cognome){
this.persona=persona;
this.cognome=cognome;
}
Costruttore secondario

Costruttore che estende il costruttore “Persona”

function Programmatore(nome,cognome,linguaggio){
Persona.call(this,nome,cognome);
this.linguaggio=linguaggio;
Programmatore.prototype = Object.create(persona.prototype);
}
Note: ricordiamo che utilizziamo il metodo .call() per indicare che i riferimenti al this contenuti della funzione "Persona" invocata all'interno della funzione "Programmatore" fanno qui riferimento a "Programmatore" e non a "Persona".

A questo punto, avremmo potutoutilizzare i metodi visti recentemente:

  • Reflect.apply() per richiamare il costruttore “Persona” ed impostre il this
  • Reflect.setPrototypeOf() e per l’attribuzione del prototipo di riferimento.
function Programmatore(nome,cognome,linguaggio){
Reflect.apply(Persona, this, [nome,cognome]);
this.linguaggio=linguaggio;
Reflect.setPrototypeOf(Programmatore, Persona);
}
Uso di Reflect.construct() con costruttore
var marioRossi = Reflect.construct(Persona, ["Mario", "Rossi"]);
var marioRossi = Reflect.construct(Programmatore, ["Mario", "Rossi", "Javascript"]);

Equivalente a:

var marioRossi = new Persona("Mario", "Rossi");
var marioRossi = new Programmatore("Mario", "Rossi", "Javascript");
Uso di Reflect.construct() e cambio prototipo

Il metodo Reflect.construct() può essere usato anche per indicare un prototipo differente rispetto a quello indicato nel costruttore stesso.
(nel nostro caso il prototipo è indicato nel costruttore-esteso “Programmatore”)

var marioRossi = Reflect.construct(Programmatore, ["Mario", "Rossi", "Javascript"], Array);

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *