2009-09-08 10 views
15

encontrado esto en MDC pero ¿cómo si hubiera querido añadir una variable privada a la¿Cómo agregar una variable privada a este fragmento literal del objeto 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 
     } 
    } 
} 

mi modo de entender programación orientada a objetos en Javascript, tendría acceso a dataset.tables.customers.cols [0 ] si tal artículo existe
Pero si quisiera colocar una variable privada en los clientes, ¿qué aspecto tendría?
Al agregar var index = 0; se produce un error de tiempo de ejecución.

Respuesta

25

No puede tener variables "privadas" sin una función involucrada. Las funciones son la única forma de introducir un nuevo alcance en javascript.

Pero no tengas miedo, que puede agregar funciones en el lugar adecuado para obtener este tipo de funcionalidad con el objeto

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 
    }] 
}; 

Pero esto no nos ganancia mucho. Esto sigue siendo principalmente un montón de objetos literales. Estos tipos de variables "Privadas" tienen un significado cero ya que no hay métodos, nada que realmente lea o use las variables en el alcance que creamos al agregar una función (un cierre).

Pero si tuviéramos un método, podría comenzar a ser útil.

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 carece del tipo de controles de acceso que obtienes en idiomas más rígidos. Puede simular el acceso privado para los datos de los objetos usando closures, pero su ejemplo es un objeto literal, una estructura de datos simple, en lugar de un objeto construido.

Más bien depende de lo que quiera hacer con el objeto: la técnica normal para miembros 'privados' significa que solo son accesibles por funciones miembro, y requiere que use un constructor para crear el objeto. La sintaxis literal se usa para estructuras de datos u objetos livianos con datos y funciones públicas.

El problema con el uso del patrón de cierre privado es que los campos dentro de un literal están en ámbito público, pero la privacidad dada por el cierre es porque la variable se define en una función, por lo que tiene un ámbito local. Puede crear una función que clone el literal y agregue campos privados, o agregue un campo público que tenga datos privados. También puede agregar cierres como miembros, de modo que cree campos privados que sean privados en lugar de objetos privados.

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

Así dataset.secretCounter() tiene un varable c que es privada sólo a esa función.

+0

¡Oh! Creo que me has vuelto a encarrilar. Las estructuras de datos no pueden contener miembros privados ya que solo declaran los datos (¡todo es público!) Pero si reescribo esto en una clase estática/singlelton (var obj = function() {}();), podré para eso ¿Es eso correcto? Gracias. :) –

4

Las variables privadas en javascript se hacen usando la palabra clave var dentro de un cierre. Solo los métodos y atributos privilegiados pueden acceder a él. Aquí está la manera de hacerlo:

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 = nuevo conjunto de datos(); o es: var d = conjunto de datos(); – pkario

Cuestiones relacionadas