Mètodes i variables estàtiques en Javascript ES5 (sense usar “class”) sense instanciar objectes?


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’usar Object.freeze, Object.seal o Object.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.

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *