Volia replicar més o menys una variable o mètode estàtic de Java
No tractis de programar en un llenguatge com si fos un altre, al seu lloc, aprèn com funciona el nou llenguatge i segueix la seva línia. Per què vols fer servir estigui habilitat per a que s’assembli a Java? Simplement no ho facis.
El concepte de propietat o mètode estàtic en Java vol dir que aquesta propietat o mètode no depèn d’una instància, si no, de la classe mateixa. Què es entenc per això? Bé, és una mica complex, en Java existeixen els anomenats Class loaders els quals s’encarreguen de carregar les classes i registrar-les quan s’aixeca la JVM. Si defineixes una propietat o mètode estàtic, aquest és carregat també, això no passa amb variables d’instància i mètodes, ja que només es carrega la seva signatura.
en JavaScript no existeix en concepte de classes
de fet estiguis pensant que això és fals ja que en ES6 aparèixer class
, però això no funciona com la gent nova pensa. Encara creus “classes” amb class
estàs creant funcions amb el seu respectiu prototip. Això és només sintaxi, no té impacte.
No obstant això, pots * emular variables i mètodes estàtics ** mitjançant Object.defineProperty
:
function User () { }Object.defineProperty(User, 'age', { enumerable: true, configurable: true, writable: true, value: 23});Object.defineProperty(User, 'getInfo', { enumerable: true, configurable: true, writable: true, value: function () { return 'Hola, tengo ' + User.age + ' años'; }});console.log(User.getInfo());
Com pots veure, ara age
i getInfo
estan adherides a la funció User
.
Seria el més semblant a Java, veritat? No necessito crear una instància i no es heretaria el mètode a fills, no?
El que fas es diu Funció factoria i és bastant usada per crear objectes que tinguin propietats privades i per utilitzar agregació en lloc d’herència. Però en realitat, no hi ha molta diferència, la diferència és que usat una funció constructora (new
) afegeixes un context (this
) a la instància, fora d’això, totes dues estan creant objectes.
function CreateBall (props) { let stub = { color, weight } = props; return { color: stub.color, weight: stub.weight, changeColor (color) { stub.color = color; }, changeWeight (weight) { stub.weight = weight; }, info () { console.log(stub.color, stub.weight); } };}const myBall = new CreateBall({ color: 'blue', weight: 5});// encapsulamientomyBall.color = 'red';myBall.weight = 7;myBall.info();myBall.changeColor('red');myBall.changeWeight(7);myBall.info();
a part si em interessés que un mètode o variable no es pogués sobreescriure, sense afectar altres variables i mètodes, podria usar
Object.defineProperty
per fer variables i mètodes estàtics que no es poguessin sobrecarregar sense haver d’usarObject.freeze
,Object.seal
oObject.preventExtensions
?
L’avantatge de Object.defineProperty
és que et dóna més flexibilitat: pots fer-readonly, no fer-la enumerable, etc. D’altra banda, Object.freeze
evita que se li puguin afegir noves propietats a un objecte, eliminar o editar les ja existents. És com si li posessis un cadenat; útil en casos on no vols que editen un objecte, per exemple, per seguretat, etc.
El mètode Object.seal
fa una cosa similar: evita que anyades noves propietats i que canviïs la configuració de les ja existents, però les propietats poden ser canviades.
El mètode Object.preventExtensions
prevé que s’afegeixin noves propietats com a pròpies, però es poden afegir propietats directament en el seu prototip.