Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    [JS OOP] Errore di scope in IE

    Nell'utilizzo del metodo apply() ho riscontrato un'altra anomalia su IE:
    non è possibile definire variabili globali se esistono degli elementi con l'ID uguale al nome della variabile, perché IE ammette l'accesso agli elementi via ID non solo attraverso il metodo DOM-standard getElementById(), ma anche con window.elementID

    E' un vero stress perché non solo il metodo è difforme dagli standard, ma perché prevale anche sulla scrittura delle variabili dall'interno di metodi come apply/call.

    Esempio:

    Codice PHP:
    <div id="c">div "c"</div>

    <
    script type="text/javascript">
    function 
    oClass(fn) {
        
    this.fn fn;
        
    this.pass = function() {
            
    this.fn.apply(window, []);
        };
    }

    var 
    obj = new oClass(function() {
        
    "Sono globale!";
    });

    alert("window.c = " window.c);
    obj.pass();
    alert("c = " c);
    </script> 
    Chiaramente su FF tutto come ci si aspetta, su IE invece no...
    Era noto questo limite di apply/call su IE?
    Se sì, ci sono dei workaround che potete segnalare?
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

  2. #2
    Mmm, la questione a mio avviso è un pelo discutibile:
    codice:
    var obj = new oClass(function() {
        c = "Sono globale!";
    });
    Tu puoi dire che una cosa simile dovrebbe applicare alla varibile appartenente allo scope della funzione, window in questo caso, il valore passato, ma, personalmente, io direi che ha ragione explorer a non farlo: il modo corretto di eseguire l'associazione delle variabili allo scope della funzione corrente è usando il this, nel modo seguente.

    codice:
    var obj = new oClass(function() {
        this.c = "Sono globale!";
    });
    in questo modo non c'è da sbagliarsi su cosa sia quella variabile, non è globale, né locale alla funzione (come se mettessi var), è una variabile dello scope della funzione.
    I DON'T Double Click!

  3. #3
    Originariamente inviato da artorius
    Mmm, la questione a mio avviso è un pelo discutibile:
    codice:
    var obj = new oClass(function() {
        c = "Sono globale!";
    });
    Tu puoi dire che una cosa simile dovrebbe applicare alla varibile appartenente allo scope della funzione, window in questo caso, il valore passato, ma, personalmente, io direi che ha ragione explorer a non farlo: il modo corretto di eseguire l'associazione delle variabili allo scope della funzione corrente è usando il this, nel modo seguente.

    codice:
    var obj = new oClass(function() {
        this.c = "Sono globale!";
    });
    in questo modo non c'è da sbagliarsi su cosa sia quella variabile, non è globale, né locale alla funzione (come se mettessi var), è una variabile dello scope della funzione.
    Innanzitutto scrivere
    var c = "Sono globale!";
    oppure
    this.c = "Sono globale!";
    non è per niente equivalente, anzi è totalmente diverso: con la prima notazione definisci una variabile privata, con la seconda notazione definisci un membro privilegiato, ovvero non solo pubblico, ma anche in grado di accedere esso stesso (qualora si tratti di un metodo) a variabili private.

    Dal momento che a me la variabile serve globale, non posso usare il costruttore var che la renderebbe privata, cioè disponibile solo nello scope della funzione.

    Secondo la logica dello scope di Javascript, un metodo del super-object window che definisce una variabile senza costruttore var la rende disponibile per l'oggetto window stesso, o, se preferisci in chiave non OOP, la rende globale.

    Per questo mi aspettavo quel comportamento.

    Se ti interessa:
    http://www.dustindiaz.com/javascript...ic-privileged/
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

  4. #4
    Codice PHP:
    function mytest(fn){
        
    fn.call(window);    
    }
    mytest(function() {
        
    "Sono globale!";
    });
    alert("window.c = " window.c); 

    alert("c = " c); 
    qui ie va per lucciole
    adesso su FF e Opera
    funziona prima FF dava
    undefined a window.c
    Opera dava object e string
    ie 6 object e poi andava
    per lanterne.





    PS


    imho c è globale a livello di scope.
    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  5. #5
    Originariamente inviato da whisher
    Codice PHP:
    function mytest(fn){
        
    fn.call(window);    
    }
    mytest(function() {
        
    "Sono globale!";
    });
    alert("window.c = " window.c); 

    alert("c = " c); 
    qui ie va per lucciole
    adesso su FF e Opera
    funziona prima FF dava
    undefined a window.c
    Opera dava object e string
    ie 6 object e poi andava
    per lanterne.





    PS


    imho c è globale a livello di scope.

    Sì, avevo notato anch'io lo sfarfallamento

    Ho usato volutamente apply() con array vuoto come parametro perché call() ha un comportamento ancora più difforme tra i browser standard e IE rispetto ad apply().

    Insomma niente da fare, il trucco dello script append resta la migliore soluzione crossbrowser:
    http://webreflection.blogspot.com/20...n-and-dom.html
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

  6. #6
    Colgo l'occasione per segnalare

    http://www.packtpub.com/object-orien...libraries/book

    da 10 e lode

    e meditare su questo codice

    Codice PHP:
    function Hero(name) {
        
    this.name name;
    }
    var 
    Hero('Leonardo');
    alert(name);
    alert(window.name);

    function 
    C2() {
        
    this.1
        return {
    b2};
    }
    var 
    c2 = new C2();
    alert(typeof c2.a);
    alert(c2.b); 

    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  7. #7
    Originariamente inviato da whisher
    Colgo l'occasione per segnalare

    http://www.packtpub.com/object-orien...libraries/book

    da 10 e lode

    e meditare su questo codice

    Codice PHP:
    function Hero(name) {
        
    this.name name;
    }
    var 
    Hero('Leonardo');
    alert(name);
    alert(window.name);

    function 
    C2() {
        
    this.1
        return {
    b2};
    }
    var 
    c2 = new C2();
    alert(typeof c2.a);
    alert(c2.b); 

    Grazie della segnalazione, libro interessante.

    Nel secondo caso (classe C2) non si avrà mai accesso ad un oggetto della classe C2 perché vai a modificare il return this implicito che avviene di default quando istanzi un oggetto, e al posto di quello gli dici di restituire sempre l'oggetto {b: 2} creato a runtime, che non ha alcuna proprietà "a" definita.

    Il primo caso invece rivela la criticità di IE con cui mi sono scontrato: se nella classe Hero si prova a sostituire
    this.name = name
    con
    name = name

    sembra di capire che il parser di IE non legge l'espressione da destra verso sinistra come dovrebbe.
    La variabile name che si vuole definire prima dell'operatore di assegnazione "=" non ha ancora un valore ma IE la mette già nello stack, e se è uguale a sé stessa vuol dire che non ha valore.
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

  8. #8

    Re: [JS OOP] Errore di scope in IE

    Originariamente inviato da emanueledg
    Nell'utilizzo del metodo apply() ho riscontrato un'altra anomalia su IE:
    non è possibile definire variabili globali se esistono degli elementi con l'ID uguale al nome della variabile
    falso, nel tuo caso non funziona poichè non hai esplicitato la dichiarazione della variabile globale c
    , perché IE ammette l'accesso agli elementi via ID non solo attraverso il metodo DOM-standard getElementById(), ma anche con window.elementID
    giusto, è per questo che hai ottenuto lo "strano effetto"
    E' un vero stress perché non solo il metodo è difforme dagli standard, ma perché prevale anche sulla scrittura delle variabili dall'interno di metodi come apply/call.
    Basta definire prima le variabili globali.
    Esempio:

    codice:
    <div id="c">div "c"</div>
    
    <script type="text/javascript">
    var c;
    function oClass(fn) {
        this.fn = fn;
        this.pass = function() {
            this.fn.apply(window, []);
        };
    }
    
    var obj = new oClass(function() {
        c = "Sono globale!";
    });
    
    alert("window.c = " + window.c);
    obj.pass();
    alert("c = " + c);
    </script>
    Chiaramente su FF tutto come ci si aspetta, su IE invece no...
    Era noto questo limite di apply/call su IE?
    Se sì, ci sono dei workaround che potete segnalare?
    considerazioni:
    Considera che caricare lo script così potrebbe cagionar problemi di caricamento: usa l' evento onload (o similari) per sicurezza.

    In realtà eseguire javascript all' interno di un browser equivale eseguire il codice all' interno di un with(window){...}, per cui le variabili "globali" in realtà son figlie di window.

    Usar le variabili globali, oltre che essere un pelo più lento implica quasi certamente un cattivo design del codice

  9. #9
    Originariamente inviato da emanueledg
    Insomma niente da fare, il trucco dello script append resta la migliore soluzione crossbrowser:
    http://webreflection.blogspot.com/20...n-and-dom.html
    emanue' ... ancora? ma perche' vuooi perdere altro tempo dietro un problema gia' affrontato e risolto anni fa da tantissimi sviluppatori? cosa non ti piace di quel metodo e perche'? Hai mai considerato il fatto che tutto quello che stai tentando di fare l'abbiamo gia' fatto prima di te anche noi?

    comunque ho letto diversi strafalcioni in generale ... venite tutti e due (emanueledg e whisher) da PHP dove scope iniettato sul this, nested scope e lambda sono completamente diversi (assenti).

    scrivere var significa dichiarare la variabile locale ... e' una convenzione chiamare queste variabili private perche' di privato non hanno niente, solo lo scope di appartenenza.

    this.qualunquecosa non e' proprieta' privilegiata ma semplicemente pubblica, e' una convenzione definirle privilegiate ma se lo scope e' undefined, null, false, "", o window, (che sono tutti la stessa cosa) il this sara' riferito all'oggetto globale.

    Per finire, quando si chiama una call o una apply non ha senso passare l'oggetto window, anzi, e' sconsigliato perche' scrivere window implica risoluzione di scope per trovare la variabile (stessa cosa per undefined) mentre null e' costante nulla che non richiede risoluzione di scope.

    codice:
    (function(){
    this === window; // true
    var window = 123;
    // quintali di codice ... e poi ...
    (function(){
    // quello che vuoi
    }).call(window); // window deve essere interpretato, null NO
    })();
    se avete altri dubbi su scope e metodi rilinco la vecchia ma ancora buona pillola che scrissi anni fa piu' questa pagina:
    http://www.3site.eu/doc/



    P.S. quando avro' finito di editare il libro gliela date una letta? ( dovrebbe uscire questo autunno in U.S.A. )
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  10. #10
    OT: sborò cerca di non cambiare l url che l'ho già linkata in diversi posti
    esempio:

    http://stackoverflow.com/questions/7.../725405#725405




    fine OT

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.