Bookmark and Share
Document Actions

Javascript e l'uguaglianza
medio

Malizie di javascript: controlliamo se due variabili hanno lo stesso contenuto

Il problema

La particolare tipizzazione (debole e dinamica) rende complesso il confronto di variabili javascript.

Ad esempio abbiamo due diversi operatori di uguaglianza e diversità:

== e != cercano di convertire il tipo in stringa (utilizzando il metodo toString) prima del confronto.

=== e !== non convertono il tipo

Quindi :

>>>100 == "100"
true

mentre

>>>100 === "100"
false

e infine

>>>100 === 100
true

E' consigliabile quindi utilizzare sempre === e !== (o almeno essere consapevoli di cosa comporta l'utilizzo dell'operatore == ).

Quando confrontiamo tipi complessi ci troviamo un altro problema ! A quanto pare due variabili oggetto sono uguali solo se sono in effetti lo stesso oggetto.

Quindi:

>>>var obj1 = {"value":1}
>>>var obj2 = obj1;
>>>obj1 == obj2
true

mentre

>>>var obj1 = {"value":1}
>>>var obj2 = {"value":1}
>>>obj1 == obj2
false

Inoltre ogni oggetto può contenere un altro oggetto!

Dobbiamo quindi testare ricorsivamente ogni attributo.

La soluzione

Ecco la soluzione che ho trovato:

function equals (obj1,obj2){
   if (obj1 === null || obj2 === null){
       return obj1 === obj2;
   }
   switch(typeof(obj1)){
       case 'object':
           if (typeof(obj2) == 'object'){
               for (i in obj2){ // object or array
                   if (typeof(obj1[i]) == "undefined"){
                       return false;
                   }
               }
               for (i in obj1){
                   if (! arguments.callee(obj1[i],obj2[i])){
                       return false; //if are not equals return false
                   }
               }
               return true;
           }
           break;
       case 'function':
           if ((typeof(obj2) == 'function') && (obj1.toString() == obj2.toString())){
               return true;
           }
           break;
       default:
           if (obj1 === obj2){
               return true;
           }
   }
   return false;
}

Come prima cosa controllo se uno dei due oggetti è null. A quanto pare, nonostante null sia un "object", il confronto tra due null funziona correttamente.
Poi a seconda del tipo faccio un diverso tipo di confronto: se il tipo è "function" controllo l'uguaglianza tramite il metodo toString che restituisce il sorgente della funzione. In caso di oggetto (ricordo che in javascript gli array hanno tipo "object") controllo in primo luogo se i membri (metodi e gli attributi) del secondo oggetto sono definiti nel primo, in seguito lancio ricorsivamente la funzione su ogni coppia di membri verificando quindi che siano uguali.
In caso che il tipo sia diverso da "function" e da "object" considero che il tipo sia primitivo (number, string, undefined) e tra questi il confronto funziona correttamente (con ===).
by Maurizio Lupo last modified 2010-07-23 18:05
 

Supporto

Ottieni un
aiuto veloce e mirato sul forum, gratis!

partecipa al forum

 

Segui le icone

 

Livelli di difficoltà

livello guruSolo per i "guru"!
livello avanzatoPer configuratori e sviluppatori
livello medioPer chi ha già familiarità
livello basePer tutti!

 

I video

video

Il documento è supportato da un video!