97 votes

Définir la valeur par défaut des attributs des objets Javascript

Existe-t-il un moyen de définir l'attribut par défaut d'un objet Javascript de telle sorte que :

let emptyObj = {};
// do some magic
emptyObj.nonExistingAttribute // => defaultValue

0 votes

TOUT attribut non existant ou simplement un nom d'attribut CONNU ?

1 votes

let o = new Proxy({}, { get: (o, k) => k in o ? o[k] : 'some default value' }; console.log(o.key1)

138voto

sandstrom Points 2420

Depuis que j'ai posé la question il y a plusieurs années, les choses ont bien progressé.

Les mandataires font partie de l'ES6. L'exemple suivant fonctionne dans Chrome, Firefox, Safari et Edge :

let handler = {
  get: function(target, name) {
    return target.hasOwnProperty(name) ? target[name] : 42;
  }
};

let emptyObj = {};
let p = new Proxy(emptyObj, handler);

p.answerToTheUltimateQuestionOfLife; //=> 42

Lire la suite dans Documentation de Mozilla sur les Proxies .

0 votes

Si vous envisagez de prendre en charge Internet Explorer (avant Edge), vous n'avez pas de chance : caniuse.com/#search=proxy De plus, le polyfill github.com/tvcutsem/harmony-reflect ne supporte pas IE

28 votes

Félicitations, vous avez gagné Phoenix (Insigne d'or : répondre à l'une de vos propres questions au moins un an plus tard, avec une réponse qui a au moins doublé le nombre de votes de la réponse la plus populaire)

2 votes

Object.withDefault=(defaultValue,o={})=>new Proxy(o,{get :(o,k)=>(k in o)?o[k]:defaultValue}) ; o=Object.withDefault(42) ; o.x //=> 42 o.x=10 o.x //=> 10 o.xx //=> 42

42voto

alexdriedger Points 1229

Utilisez déstructuration (nouveau dans ES6)

Il y a une grande documentation par Mozila ainsi qu'un fantastique article de blog qui explique la syntaxe mieux que je ne le peux.

Pour répondre à votre question

var emptyObj = {};
const { nonExistingAttribute = defaultValue } = emptyObj;
console.log(nonExistingAttribute); // defaultValue

Aller plus loin

Est-ce que je peux renommer cette variable ? Bien sûr !

const { nonExistingAttribute: coolerName = 15} = emptyObj;
console.log(coolerName); // 15

Qu'en est-il des données imbriquées ? Allez-y !

var nestedData = {
    name: 'Awesome Programmer',
    languages: [
        {
            name: 'javascript',
            proficiency: 4,
        }
    ],
    country: 'Canada',
};

var {name: realName, languages: [{name: languageName}]} = nestedData ;

console.log(realName); // Awesome Programmer
console.log(languageName); // javascript

28voto

nrabinowitz Points 27991

Il n'y a pas de moyen de définir ceci en Javascript - en retournant undefined pour les propriétés inexistantes fait partie de la spécification de base de Javascript. Voir la discussion pour cette question similaire . Comme je l'ai suggéré ici, une approche (bien que je ne puisse pas vraiment la recommander) consisterait à définir une fonction globale getProperty fonction :

function getProperty(o, prop) {
    if (o[prop] !== undefined) return o[prop];
    else return "my default";
}

var o = {
    foo: 1
};

getProperty(o, 'foo'); // 1
getProperty(o, 'bar'); // "my default"

Mais cela conduirait à un tas de code non standard qui serait difficile à lire pour les autres, et cela pourrait avoir des conséquences inattendues dans des domaines où l'on s'attendrait ou voudrait une valeur non définie. Il est préférable de vérifier au fur et à mesure :

var someVar = o.someVar || "my default";

13voto

Kiyan Points 91

Mon code est :

function(s){
    s = {
        top: s.top || 100,    // default value or s.top
        left: s.left || 300,  // default value or s.left
    }
    alert(s.top)
}

2 votes

C'est la solution que je préfère, car elle est similaire à ce que je fais en PHP. function foo( array $kwargs = array() ) { // Fill in defaults for optional keyworded arguments. $kwargs += array( 'show_user' => true, 'show_links' => false, ); ...

0 votes

Et que se passe-t-il si 's' est indéfini (c'est-à-dire non spécifié du tout) ?

0 votes

@didzis Tu pourrais faire function(s = {}) ce qui corrigerait le fait de ne pas le remplir du tout. Mais vous pourriez aussi ajouter ceci sur la première ligne de la fonction : s = s || {} pour réparer le fait de ne pas le remplir et aussi réparer null ou undefined comme paramètres. Vous pouvez aussi le faire en ligne, mais ce n'est pas recommandé : top: (s || {}).top || 100

11voto

jfriend00 Points 152127

Cela ressemble à l'utilisation typique d'objets basés sur des prototypes :

// define a new type of object
var foo = function() {};  

// define a default attribute and value that all objects of this type will have
foo.prototype.attribute1 = "defaultValue1";  

// create a new object of my type
var emptyObj = new foo();
console.log(emptyObj.attribute1);       // outputs defaultValue1

0 votes

Si vous appelez console.log(emptyObj), il renvoie {}. not { attribute1 : 'defaultValue1' }

2 votes

Oui, parce que attribute1: defaultValue1 est sur le prototype et console.log énumère uniquement les éléments définis sur l'objet de niveau supérieur, pas sur le prototype. Mais, la valeur est là comme mon console.log(emptyObj.attribute1) montre.

0 votes

C'est juste mais c'est le même problème avec JSON.stringify(emptyobj) . J'ai été obligé de créer une méthode qui renvoie tous les attributs en réponse à ce problème

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X