Domanda

Diciamo che ho un oggetto JavaScript come:

var obj = {};
obj.computers = {};
obj.computers.favorite = "Commodore 64";
obj.computers.popular = "Apple";

Ora posso facilmente verificare la presenza di null come:

if(obj != 'undefined' && obj != null) {
    if(obj.computers != 'undefined' && obj.computers != null)) {
        .....

Come puoi vedere, se ho bisogno di vedere se obj.computers.favorite è stato impostato, devo davvero annidare lì una logica condizionale.Alcuni dei nostri oggetti raggiungono 3, 4, 5 livelli di profondità.

Questo è quello che mi piacerebbe poter fare:

var fav = obj.computers.favorite || 'Unknown';

Ma mi rendo conto che avrei bisogno di racchiuderlo in qualche modo.Qualcosa di simile a:

var fav = getValueOrDefault(obj.computers.favorite, 'Unknown');

Suggerimenti apprezzati.

Grazie

MODIFICARE

Il mio controllo per "undefinito" non è in realtà quello che utilizzo.Mi è appena uscito dalla testa quando ho posto la domanda.lol

Ma mi chiedevo, potrei semplicemente racchiudere un try/catch and launch default se eccezione?

function(obj, default) {
    try {
        if(obj != null) {
            return obj;
        } else {
            return default;
        }
    } catch(ex) {
        return default;
    }
}

Inoltre, grazie a Shusi per aver segnalato le variabili ridondanti.

È stato utile?

Soluzione

Puoi farlo con a aiutante funzione.Se ho capito bene il tuo problema, i tuoi oggetti poter avere oggetti profondi arbitrari e desideri accedere a queste proprietà nidificate arbitrarie senza ingombrare il codice.Ho costruito un Nested funzione che ti consente get() proprietà arbitrarie se sono impostate o predefinite in caso contrario.

var Nested = function() {};
// prop is a dot-separated path like "foo.bar.baz"
Nested.prototype.get = function(prop, _default) {
    var current = this;
    $.each(prop.split("."), function(i, e) {
        current = current[e] || undefined;
        if (current == undefined)
            return false;
    });
    return current || _default;
}

Puoi quindi scrivere codice come questo

var fav = obj.get("computers.favourite", "Linux");
// this emulates
var fav = obj.computers.favourite || "Linux"; // throws error

Come puoi vedere, non è tanto più scrivere.Certo, non sembra Javascript normale... Ecco il violino.

Altri suggerimenti

Puoi davvero scrivere:

(obj && obj.computers && obj.computers.favorite) || 'Unknown'
.

Ho scritto questo per aiutarti a gestire una delle tue domande: " Devo vedere se OBJ.COMPUTERS.Favorite è stato impostato ".

Object.prototype.isset = function (/* string */ full_path)
{
    var props = full_path.split('.');
    var self = this; /* note that self is usually the window object */

    for (var ii = 0; ii < props.length; ++ii)
    {
        var prop = props[ii];
        var hasMoreComing = ii < props.length - 1 ? true : false;

        if (self[prop] !== null && typeof self[prop] === 'object' && hasMoreComing)
        {
            self = self[prop];
            continue;   // Move up one level.
        }
        else if (hasMoreComing)
            return false;    // ..because user queries a subproperty of a value type

        return self.hasOwnProperty(prop);
    }
};
.

Codice test:

var test = {};

test.kuk = {};
console.log( test.isset('kuk') );  // Prints true.

test.kuk.fitta = {};
console.log( test.isset('kuk.fitta') ); // Prints true.

test.kuk.fitta = null;
console.log( test.isset('kuk.fitta') ); // Prints true.

test.kuk.fitta = undefined;
console.log( test.isset('kuk.fitta') );  // Prints true

delete test.kuk.fitta;
console.log( test.isset('kuk.fitta') );  // Prints false

test.kuk.fitta = 123;
console.log( test.isset('kuk.fitta.doesnt.exist') );  // Prints false
.

Sfortunatamente, non c'è un modo super facile di aggirarti questo, ma non è necessario verificare sia nullo che non definito.Perché nullo e indefinito sono entrambi falsi, puoi semplicemente fare:

if (obj && obj.computers) {
  var fav = obj.computers.favorite || 'unknown';
}
.

Non va in realtà intorno a ciò che è il tuo reclamo, ma è meno doloroso di quello che credevi.

La seguente funzione prenderà la stringa come parametro e oggetto di ritorno se esiste

 function getValueOrDefault(str , obj, deflt){
    var a = str.split("."); o = obj;
    for(var i =0; i < a.length; i++){
         o = obj[a[i]];
         if(!o){
           return deflt;
         }
    }
      return o;
}

var obj = {};
obj.computers = {};
obj.computers.favorite = "Commodore 64";
obj.computers.popular = "Apple";
getValueOrDefault('computers.favorite', obj, 'Unknown');
.

Nota: non è necessario utilizzare VAR durante l'assegnazione di proprietà all'oggetto ad esempio.var obj.computers.favorite è l'errore di sintassi.

Puoi anche farlo con JavaScript ES5 Funzione reduce:

function get(root, member) {
    return member.split('.').reduce((acc, value) => {
        return (acc && typeof acc[value] !== 'undefined') ? acc[value] : undefined
    }, root);
}
.

Fa una matrice fuori dalla stringa del membro, l'accumulatore è progressivamente attraversato nell'oggetto in quanto i membri sono ridotti.

Puoi usarlo come questo, anche con gli array:

let obj = {
    computers : {
        favorite : "Commodore 64",
        popular : "Apple",
        list: [
            {
                sn : "TDGE52343FD76",
                price: "9867.99",
                options: {
                    fanless: true
                }
            }
        ]
    }
}

get(obj, 'computers.popular');
// => "Apple"
get(obj, 'computers.list.0.sn');
// => "TDGE52343FD76"
get(obj, 'computers.list.0.options.fanless');
// => true
get(obj, 'computers.list.0.options.runsWithoutEletricity');
// => undefined
get(obj, 'computers.list.0.options.runsWithoutEletricity') || "too bad..." ;
// => "too bad..."
.

C'è un codepen a ACQUISTA SICURO TRAVERSE JS Oggetto

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top