2009-09-08 6 views
15

Trouvé ce au MDC, mais comment si je l'avais voulu ajouter une variable privée auComment ajouter une variable privée à cet extrait de littéral d'objet Javascript?

var dataset = { 
    tables:{ 
     customers:{ 
      cols:[ /*here*/ ], 
      rows:[ /*here*/ ] 
     }, 
     orders:{ 
      cols:[ /*here*/ ], 
      rows:[ /*here*/ ] 
     } 
    }, 
    relations:{ 
     0:{ 
      parent:'customers', 
      child:'orders', 
      keyparent:'custid', 
      keychild:'orderid', 
      onetomany:true 
     } 
    } 
} 

La façon dont je comprends la POO en Javascript, j'avoir accès à dataset.tables.customers.cols [0 ] si un tel article existe.
Mais si je voulais placer une variable privée dans les clients, à quoi cela ressemblerait-il? L'ajout de entraîne une erreur d'exécution.

Répondre

25

Vous ne pouvez pas avoir de variables "privées" sans une fonction impliquée. Les fonctions sont le seul moyen d'introduire une nouvelle portée en javascript.

Mais jamais peur, vous pouvez ajouter des fonctions au bon endroit pour gagner ce genre de fonctionnalité avec votre objet

var dataset = { 
    tables: { 
    customers:(function(){ 
     var privateVar = 'foo'; 
     return { 
     cols:[ /*here*/ ], 
     rows:[ /*here*/ ] 
     } 
    }()), 
    orders:{ 
     cols:[ /*here*/ ], 
     rows:[ /*here*/ ] 
    } 
    }, 
    relations: [{ 
    parent:'customers', 
    child:'orders', 
    keyparent:'custid', 
    keychild:'orderid', 
    onetomany:true 
    }] 
}; 

Mais beaucoup ne nous gagne pas. C'est encore la plupart du temps juste un tas d'objets littéraux. Ces types de variables "privées" n'ont aucune signification car il n'y a pas de méthodes - rien qui pourrait réellement lire ou utiliser les variables dans la portée que nous avons créée en ajoutant une fonction (une fermeture). Mais si nous avions une méthode, cela pourrait effectivement commencer à devenir utile.

var dataset = { 
    tables: { 
    customers:(function(){ 
     var privateVar = 'foo'; 
     return { 
     cols:[ /*here*/ ], 
     rows:[ /*here*/ ], 
     getPrivateVar: function() 
     { 
      return privateVar; 
     } 
     }; 
    }()), 
    orders:{ 
     cols:[ /*here*/ ], 
     rows:[ /*here*/ ] 
    } 
    }, 
    relations: [{ 
    parent:'customers', 
    child:'orders', 
    keyparent:'custid', 
    keychild:'orderid', 
    onetomany:true 
    }] 
}; 

alert(dataset.tables.customers.getPrivateVar()); 
9

JavaScript manque le type de contrôle d'accès que vous obtenez dans des langages plus rigides. Vous pouvez simuler l'accès privé pour les données d'objets en utilisant closures, mais votre exemple est un littéral d'objet - une structure de données simple - plutôt qu'un objet construit. Cela dépend plutôt de ce que vous voulez faire avec l'objet - la technique normale pour les membres 'privés' signifie qu'ils sont accessibles uniquement par les fonctions membres, et nécessite que vous utilisiez un constructeur pour créer l'objet. La syntaxe littérale est utilisée pour les structures de données ou les objets légers avec des données et des fonctions publiques. Le problème avec l'utilisation du modèle de fermeture privé est que les champs dans un littéral sont dans la portée publique, mais la confidentialité donnée par la fermeture est parce que la variable est définie dans une fonction, donc est portée localement. Vous pouvez soit créer une fonction qui clone le littéral et ajoute des champs privés, soit ajouter un champ public contenant des données privées. Vous pouvez également ajouter des fermetures en tant que membres, donc créez des champs privés qui sont des méthodes privées plutôt que des objets privés.

dataset = { 
    secretCounter: ( 
     function() { 
     var c = 0; 
     return function() { return ++c; } 
    })(),  
    ... 

Alors dataset.secretCounter() a une varable c qui est privé à cette fonction uniquement.

+0

Oh! Je pense que tu m'as remis sur les rails. Les structures de données ne peuvent pas contenir des membres privés puisqu'ils déclarent simplement les données (tout est public!) Mais si je réécris ceci dans une classe statique/singlelton (var obj = function() {)();), je serai capable de à tellement. Est-ce exact? Je vous remercie. :) –

4

Les variables privées dans javascript sont effectuées en utilisant le mot-clé var dans une fermeture. Seules les méthodes et attributs privilégiés peuvent y accéder. Voici la façon de le faire:

function dataset() 
{ 
var private_stuff = 10; // private 
this.foo = new function() { alert(private_stuff); } // priviliged 
return { 
    tables:{ 
     customers:{ 
       cols:[ ], 
       rows:[ ] 
     }, 
     orders:{ 
       cols:[ ], 
       rows:[ ] 
     } 
    }, 
    relations:{ 
     0:{ 
       parent:'customers', 
       child:'orders', 
       keyparent:'custid', 
       keychild:'orderid', 
       onetomany:true 
     } 
    } 
}; // public 
} 

var d = new dataset; 
alert(d.foo()); 
+2

var d = nouveau dataset(); ou est-ce: var d = dataset(); – pkario

Questions connexes