Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    Javascript Alla Deriva: La Geometrica Potenza Della Specifica Inutile

    Allora, prendiamo in esame questa caratteristica e forniamo uno spunto per chi volesse ragionare (in assenso o dissenso, è immateriale: va tutto bene): defineProperty.

    Il significato di questa sintassi è: assegnare ad un oggetto, ad esempio
    var foo={}
    le sue proprietà.

    Un tempo facevi (ad esempio)
    var foo{'ciao':'hallo'}
    oppure
    var foo{}
    foo.ciao='hallo'
    oppure
    var foo=[]
    foo['ciao']='hallo'.

    Tutta internet va avanti, con siti dello spessore di Amazon e quant' altro, usando queste sintassi.

    Cosa introduce invece definire la proprietà con Object.defineProperty ?
    Questo: che puoi settare se:
    è writable: se puoi riassegnarli un valore
    è enumerable: se passando ad un loop l'oggetto, la proprietà ti apparirà come esistente o meno (uh, che caratteristica interessantissima...! ci perdevamo il sonno ad attenderla)
    è configurable: se puoi, ad esempio, cancellarla.

    Ora, cosa c'è dietro questo approccio? Fondamentalmente, il nulla. Mozilla e le specifiche cioè (verso le quali sono critico da anni e anni poichè è invalso il costume di seguirle con venerazione acritica, anche quando sbagliano - oh sì, anche loro sbagliano - e inducono ad applicarle perchè fa moda - quel che da anni io chiamo "Codice Armani" - e non perchè serve o se ne è compresa la utilità) stanno perseguendo una agenda nascosta che non è dichiarata, ma che è ovvia.

    Essa è composta da due obbiettivi.

    Il primo, a mio avviso pericolosissimo: quello di incoraggiare la programmazione per ambienti dove il programmatore non ha alcun reale controllo - infatti se io ho il controllo di un ambiente, non mi serve settare una proprietà a non scrivibile: se i miei codici sono robusti, e ne ho come dovrei il pieno controllo, i miei codici non scriveranno dove non devono.
    Queste sintassi mi incoraggiano, subdolamente, a perdere il controllo confidando nel fatto che un pezzo di codice compenserà alla carenza o negligenza umana.

    Il secondo: javascript, linguaggio non fortemente tipizzato e nato senza le caratteristiche davvero object oriented di java, si sente figlio di un dio minore, e cerca disperatamente di ovviare alla sua identità percepita come vergognosa, tentando di divenire quel che non potrà mai essere: un linguaggio di alto livello - cosa che appunto non potrà mai essere, perchè opera sul lato client e non potrai mai chiedere ad un client (e a tutta la galassia di marche e versioni e sottoversioni dei browsers diversi e di utenti occasionali che hanno l'autoupdate off per motivi che chissà quali...) di operare con i processori che permettano la gestione delle librerie di un C o di un Java - guardate in questo contesto il grande futuro che hanno avuto dietro le spalle le applet java, e il ridicolo di cui si copersero con il loro motto (che forse alcuni ricorderanno) "write once, run everywhere" - spesso trasformato in "write once, debug everywhere".

    Vale la pena aggiungere, nel contesto di questa seconda osservazione, che il motivo per cui linguaggi come Java o C sono fortemente tipizzati non è nè è mai stato quello di permettere al programmatore di non effettuare operazioni che il programmatore stesso ha voluto illecite sollevandolo dalla incombenza di scrivere codici controllati (per quanto un simile intento sia condonabile o comprensibile in codici che producono OS o GUI complesse come che so OpenOffice - ma javascript non produrrà mai cotanto codice da affidare ad un client), ma quello di garantire la velocità del processore il quale sa che tipo di dati, ad esempio, gli verranno affidati poichè gli vengono preannunziati.
    Ma della potenzialità esibita da un processore su un browser client, garantisce Pantalone e non javascript.

    Non è che dico che uno non debba usare defineProperty.
    Dico che uno dovrebbe usarla solo se le esigenze ad esempio di non rendere una proprietà visibile alla enumerazione si fanno cogenti e fondamentali per la vostra applicazione.
    Non accadrà spesso, Johnny.

    In effetti, fino ad oggi non ti era mai accaduto e semmai fosse accaduto, sapevi come domare il tuo codice.
    Perchè queste procedure presentano anche un rischio: impediscono al programmatore di rendersi conto di manovre illecite performate dal client. Un utente ad esempio dalla location bar riesce a fare una injection per alterare un mio ajax: siccome la proprietà della mia classe ajax che cercava di manipolare è settata a non writable, io non me ne accorgo, e... continuo a dialogare con questo client.

    Ma di pericoli ne abbiamo già abbastanza con i client, senza che nuove specifiche ci inducano a risolverli chiudendo gli occhi.

  2. #2
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Come vedi qui la proprietà length è numerabile e configurabile... eppure questo non l'avresti mai potuto fare senza il defineProperty...

    codice:
    var oggetto = {};
    
    Object.defineProperty(oggetto, "length", {
    	get: function() {
    		nLen = 0;
    		for (var sKey in this) { nLen++; }
    		return nLen;
    	},
    	enumerable: true,
    	configurable: true
    });
    
    alert(oggetto.length);
    
    oggetto.ciao = "mondo";
    alert(oggetto.length);
    
    oggetto.tizio = "caio";
    alert(oggetto.length);
    
    delete oggetto.tizio;
    alert(oggetto.length);
    Quest'esempio è al limite della stupidità... ma nel seguente sfortunato tentativo di creare un codice di compatibilità dell'oggetto nativo localStorage per IE 8 (sfortunato perché IE 8 supporta il defineProperty in maniera incompatibile con questo script) l'attribuzione di funzioni get e set è stata fondamentale per far sì che l'oggetto localStorage si sincronizzasse con i cookies a ogni invocazione:

    codice:
    if (!window.localStorage) {
    	Object.defineProperty(window, "localStorage", new (function () {
    		var aKeys = [], oStorage = {};
    		Object.defineProperty(oStorage, "getItem", {
    			value: function (sKey) { return this[sKey]; },
    			writable: false,
    			configurable: false,
    			enumerable: false
    		});
    		Object.defineProperty(oStorage, "key", {
    			value: function (nKeyId) { return aKeys[nKeyId]; },
    			writable: false,
    			configurable: false,
    			enumerable: false
    		});
    		Object.defineProperty(oStorage, "setItem", {
    			value: function (sKey, sValue) {
    				if(!sKey) { return; }
    				document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/";
    			},
    			writable: false,
    			configurable: false,
    			enumerable: false
    		});
    		Object.defineProperty(oStorage, "length", {
    			get: function () { return aKeys.length; },
    			configurable: false,
    			enumerable: false
    		});
    		Object.defineProperty(oStorage, "removeItem", {
    			value: function (sKey) {
    				if(!sKey) { return; }
    				var sExpDate = new Date();
    				sExpDate.setDate(sExpDate.getDate() - 1);
    				document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/";
    			},
    			writable: false,
    			configurable: false,
    			enumerable: false
    		});
    		this.get = function () {
    			var iThisIndx;
    			for (var sKey in oStorage) {
    				iThisIndx = aKeys.indexOf(sKey);
    				if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }
    				else { aKeys.splice(iThisIndx, 1); }
    				delete oStorage[sKey];
    			}
    			for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
    			for (var iCouple, iKey, iCouplId = 0, aCouples = document.cookie.split(/;\s*/); iCouplId < aCouples.length; iCouplId++) {
    				iCouple = aCouples[iCouplId].split("=");
    				if (iCouple.length > 1) {
    					oStorage[iKey = unescape(iCouple[0])] = unescape(iCouple[1]);
    					aKeys.push(iKey);
    				}
    			}
    			return oStorage;
    		};
    		this.configurable = false;
    		this.enumerable = true;
    	})());
    }

  3. #3
    codice:
    var oggetto={}
    oggetto.length=function(){var l=0; for(i in this){++l;}; return l;}
    oggetto.ciao='hallo';
    alert(oggetto.length());
    oggetto.hallo='ciao';
    alert(oggetto.length());
    "Eppur si muove!"

  4. #4
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Te l'ho detto, il primo esempio è al limite della stupidità. Nel caso del codice di compatibilità per il localStorage, si presuppone si tratti di un qualcosa da aggiungere alla pagina contenente già di per sé un uso di localStorage tipico dell'oggetto nativo.
    Ma ci sono mille altri motivi. Grazie all'Object.defineProperty puoi ad esempio modificare la funzione setter di un'oggetto nativo (come la proprietà length di un array) senza toccare la funzione getter e viceversa (e questo davvero non c'è altro modo per ottenerlo senza questa grandiosa introduzione). Del resto puoi stare tranquillo, si tratta di una funzione che non conosce e non usa nessuno se non ha necessità reali. Io stesso ad esempio, pur conoscendone l'esistenza, non avevo mai avuto necessità di usarla prima di creare quel codice di compatibilità. E quel codice di compatibilità non può essere scritto altrimenti. Perché presuppone che nella pagina in cui lo si inserisce ci siano già scritture come la seguente:

    codice:
    localStorage.ciao = "mondo";
    alert(localStorage.ciao);
    // in tutto cio' i cookies sono stati aggiornati dal mio algoritmo con la nuova proprieta' "ciao"
    e quel codice non deve fare altro che assecondarle, visto che è nato come codice "temporaneo", da lasciare in uno script per qualche anno ancora fino a quando tutti i browsers non abbiano raggiunto il pieno supporto degli oggetti Storage. Molto meglio rimuovere quel codice fra qualche anno che dover riscrivere tutto il resto.

  5. #5
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Tra l'altro è capitato anche in questo forum che qualcuno chiedesse qualcosa che gli permettesse di ottenere quello per cui è nato Object.defineProperty&hellip;

    http://forum.html.it/forum/showthrea...readid=1462767


  6. #6
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    A proposito dell'uso di myArray[myArray.length] = valore versus myArray.push(valore)&hellip; Ho scoperto che i due metodi hanno prestazioni stranamente identiche in Firefox, mentre su Chrome si conferma molto più rapido l'uso di push &ndash; impiega la metà del tempo. Ho fatto il test con un ciclo di dieci milioni di inserimenti:

    codice:
    <!doctype html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>myArray[myArray.length] vs. myArray.push()</title>
    <script type="text/javascript">
    function printElapsedTime (fTest) {
    	var nStartTime = Date.now(), vReturn = fTest(), nEndTime = Date.now();
    	alert("Elapsed time: " + String(nEndTime - nStartTime) + " milliseconds");
    	return vReturn;
    }
    
    function setNewVals () {
    	var myArray = [];
    	for (var iCount = 0; iCount < 1e7; iCount++) {
    		myArray[myArray.length] = "Ciao!";
    	}
    }
    
    function pushNewVals () {
    	var myArray = [];
    	for (var iCount = 0; iCount < 1e7; iCount++) {
    		myArray.push("Ciao!");
    	}
    }
    </script>
    </head>
    <body>
    
    
    [ <span style="cursor:pointer;text-decoration:underline;color:#0000ff;" onclick="printElapsedTime(setNewVals);">Utilizza myArray[myArray.length]</span> | <span style="cursor:pointer;text-decoration:underline;color:#0000ff;" onclick="printElapsedTime(pushNewVals);">Utilizza myArray.push()</span> ]</p>
    </body>
    </html>

  7. #7
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    A proposito di quanto può essere ad alto livello javascript&hellip; Guarda questo, è scritto in puro javascript. Clicca su "3D view"!

  8. #8
    Originariamente inviato da carlomarx
    Tra l'altro è capitato anche in questo forum che qualcuno chiedesse qualcosa che gli permettesse di ottenere quello per cui è nato Object.defineProperty&hellip;

    http://forum.html.it/forum/showthrea...readid=1462767

    In merito a questo ho inserito una risposta in quel thread: mi pareva più opportuno (sennò si rischia di aprire i thread dentro i thread).
    In effetti coglie il senso di alcune domande (anche se non vi risponde: prende posizione, ma non risponde): alcune nuove sintassi si limitano a creare con un assegnamento a proprietà di un oggetto quel che si otterrebbe egualmente con richiamo di un metodo dell' oggetto (o addirittura una banalissima funzione globale): e sembra davvero esser tutto qui.

    Per il resto evito di replicare a tutte e 4 le risposte (di cui una riguardava un altro argomento peraltro per cui non posso andar fuori tema qui) visto che provengono tutte e 4 dallo stesso utente - per carità, uno sforzo commendevole mica mi lamento, ma non voglio che sia un monologo a due ecco: non avrebbe senso e quindi non lo proseguo in tal senso.

    Mi piacerebbero anche altri pareri (se ce ne sono, ovviamente; e sennò si chiude qui oh), meglio ancora se si coglie l'aspetto che defineProperty è solo un esempio per trarre spunto su un tema più ampio: fare in altra maniera quel che già facciamo, è davvero funzionale? Sì, No, in parte, in parte è pericoloso, no è del tutto sacrosanto... insomma va bene qualsiasi risposta :-)

    Perchè staremmo introducendo queste sintassi? Ottenere con un assegnamento quel che puoi ottenere con un richiamo a dun metodo, è davvero così mission critical?
    E se lo è, come mai non ce ne siamo mai accorti prima e quali sarebbero le circostanze in cui questa criticità si rivela in tutta la sua urgenza?

    Vediamo le sintassi e vediamo gli esempi, ma non è mai spiegato il cd 'rationale' (in inglese...) che ha determinato questo pullulare di sintassi dalla implementazione incerta.
    Ad alcuni piace capire prima di codificare, e non solo seguire una moda - e purtroppo a questo riguardo (cioè il fornire il 'rationale' e lo storico del problema da cui la sintassi viene evinta) non è che la mozilla foundation brilli.

    grazie

    ps oh, non ultimo il vecchio mantra della leggibilità e portabilità dei codici.
    Se io scrivo:
    x(4)
    qualsiasi programmatore capisce che si sta sviluppando una procedura, e che potrebbe esserci altro in gioco.
    ma se io uso defineProperty con un setter e dopo 500 righe scrivo
    x=4
    in quanti si ricorderanno che assegnando ad x io sto anche lanciando una funzione magari di 50 righe, visto che il codice mi occulta completamente la natura (non peregrina invero...) della cosa?

  9. #9
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Originariamente inviato da TrueLies
    Perchè staremmo introducendo queste sintassi? Ottenere con un assegnamento quel che puoi ottenere con un richiamo a dun metodo, è davvero così mission critical?
    E se lo è, come mai non ce ne siamo mai accorti prima e quali sarebbero le circostanze in cui questa criticità si rivela in tutta la sua urgenza?
    Introduco solo un elemento in più alla discussione. L'esigenza di creare getter e setter è sempre esistita in javascript, tant'è che sin dagli albori è sempre esistita una qualche sintassi che permettesse di farlo, l'unico problema è che non era condivisa. Netscape ad esempio aveva tuoOggetto.__defineGetter__ e tuoOggetto.__defineSetter__ (provvisoria già nella sintassi), le vecchie versioni di IE avevano __getsethandler (come puoi vedere, tutte sintassi provvisorie). Tutto ciò è l'alba di javascript, fine anni '90. Non è stato introdotto nulla di nuovo, è stata solo fatta un po' di chiarezza introdocuendo finalmente una sintassi condivisa. Ergo, fare il conservatore della situazione non ha molto senso visto che nel caso specifico si tratterebbe di conservare la babele delle sintassi e niente di più.

    Originariamente inviato da TrueLies
    ps oh, non ultimo il vecchio mantra della leggibilità e portabilità dei codici.
    Se io scrivo:
    x(4)
    qualsiasi programmatore capisce che si sta sviluppando una procedura, e che potrebbe esserci altro in gioco.
    ma se io uso defineProperty con un setter e dopo 500 righe scrivo
    x=4
    in quanti si ricorderanno che assegnando ad x io sto anche lanciando una funzione magari di 50 righe, visto che il codice mi occulta completamente la natura (non peregrina invero...) della cosa?
    Infatti non è principalmente rivolta a umani quella sintassi, ma a macchine. Ci sono casi in cui l'interprete si trova automaticamente ad assegnare un valore a una proprietà di un oggetto. Facendogli trovare un setter ti consenti di manovrarlo a tuo piacimento. Lo stesso dicasi per il getter.

  10. #10
    Scusate, vorrei davvero che non fosse un monologo a due.

    la babele delle sintassi in programmazione esiste da sempre, e introdurre dieci nuove versioni di javascript con 10 nuove sintassi per fare quel che già facciamo, è assai difficilmente proponibile come un credibile sforzo inteso a... redimere babilonia.

    Se è questo quel che pensano di fare, allora è proprio la funzionalità di introdurre continuamente nuove sintassi rispetto all' obbiettivo di semplificare e garantire uno standard quel che è in discussione.

    Ora, cortesemente: vorrei non fosse un duetto. Grazie.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.