2012-09-06 13 views
6

Estoy trabajando en una utilidad para crear clases en JavaScript. Y funciona, el problema es cómo definir atributos privados.Creación de clases con propiedades privadas

Este es el código

var OO = { 

    Class:function(){ 

     var len = arguments.length; 
     var data = arguments[len-1]; 



     var Klass; 
     if (data.constructor === Object){ 
      Klass = function(){}; 

     } else { 
      Klass = data.constructor; 
      delete data.constructor;     
     } 



     OO.extend(Klass.prototype,data); //Classic Extend Method 


     return Klass; 


    }, 
//Simple extend method, just what I need in this case 
    extend: function(target, source){ 
      var prop; 
      for (prop in source) 
       target[prop] = source [prop]; 

    } 
} 

Así es como funciona

// first create a class 
var person = OO.Class ({ 
constructor: function (name, age) { 
this.name = name; 
this.age = age; 
}, 

name:'', 
age:'', 

getName: function() { 
return this.name; 
}, 

getAge: function() { 
return this.age; 
} 

}); 

Y aquí es la instancia

var one = new Person ('josh', 22); 

Y el problema:

one.age// returns 22 
one.name// returns josh 

Lo que necesito es que estas propiedades sólo se puede acceder mediante métodos como getName() y getAge()

EDIT1: Agregado función Extender

+1

Apenas se puede hacer que el uso de la solución actual. – zerkms

+6

¿Por qué algunas personas insisten en codificar JavaScript clásicamente? – AlienWebguy

+2

Puede que le interese el artículo de Douglas Crockford [Miembros privados en JavaScript] (http://javascript.crockford.com/private.html). – RobG

Respuesta

0

Actualización 1:

Aquí es el prototipo de trabajo. Funciona a excepción de

1.) Transferencia de valores de construcción a miembros privados.

Dummy values do work however. 

prueba a cabo el violín:

http://jsfiddle.net/UWRHP/11/

+0

¡se publica la implementación de ampliación! Quiero que todos los atributos sean privados, para que el usuario no pueda acceder directamente a través de instance.attrib, debe definir getters y setters. ¿Alguna idea sobre cómo hacer eso? –

+0

Lo siento, pero es un poco difícil conectarse desde aquí (soy del Caribe). En respuesta a su pregunta, edité la publicación original ya que esa implementación no existe (por el momento). Es una idea futura intentar extender desde clases para padres. –

+0

como digo antes, es difícil ponerse en línea desde aquí, así que una vez más discúlpame, por favor escribe tu implementación y la votación es para ti. Gracias por adelantado. –

-1

Cualquier variable que es parte de la interfaz del objeto (es decir, this.x y this.y) serán públicos. No podrá forzar el acceso externo a esas variables a través de getters.

Por lo tanto, siempre y cuando usted tiene un código como éste:

getAge: function() { 
    return this.age; 
} 

... no se puede evitar que esto:

var one = new Person ('josh', 22); 
console.log(one.age); 

Comprobar el artículo de Douglas Crockford Private Members in JavaScript.

+0

Basado en mi código ... cualquier idea de cómo forzar atributos para ser privados y solo accesible a través de getters? –

+0

Según su código? No. –

+1

¿Esto no es técnicamente cierto? ¿Por qué los votos a la baja? –

-1

Si usted está buscando para no complicar más las cosas (y deshacerse por completo lo que has hecho hasta ahora) como @AlienWebguy indica, Don 't siquiera necesita el miembro de .io - que al final se expone tanto como los .name y .age propiedades fueron:

john.io.set('name', 'Johnny'); // still exposed! 

Al final, el objeto .io está tan expuesto como las propiedades .name y .age, por lo que es una solución complicada que no hace ningún progreso en la encapsulación ni en la ocultación de información.(lo siento, @AlienWebguy, así es como me siento)

Si está tratando de usar un paradigma de herencia clásico y eliminar por completo el OOP de JavaScript convencional, abandone el paradigma convencional de funciones como constructores y olvídese de usar el this referencia en sus constructores:

// first create a constructor 
var Person = function(arg0, arg1) { 

    var that = {}; 

    // private variables 

    var age = arg0; 
    var name = arg1; 

    // public methods 

    that.getName = function() { 
     return name; 
    }; 

    that.getAge = function() { 
     return age; 
    }; 

    that.setAge = function(a) { 
     age = a; 
    }; 

    return that; 

}; 

var john = new Person('johnathan', 33); 

console.log(john.name);  // undefined 
console.log(john.getName()); // 'johnathan' 
console.log(john.age);  // undefined 
console.log(john.getAge()); // 33 
john.setAge(28); 
console.log(john.getAge()); // 28 
john.setName("Richard");  // Error - setName is not a function 

Este es un ejemplo de Douglas Crockford Parasitic Inheritance ... pero sin la parte de "la herencia". El punto es que las variables de instancia age y name son privadas, pero permanecen en el alcance debido al alcance de la variable funcional de JavaScript, por lo que los métodos del objeto aún pueden manipularlas.

También se dará cuenta de que la variable no tiene name organismo, por lo que esta técnica legítimamente le permitirá controlar el acceso a la variable name - no hay ni oculto this.namethis.io que permitirá la variable a ser manipulado; es completamente privado.

+0

Crear vars locales 'age' y' name' es redundante y confuso. – Maverick

+0

@Stylez - ¿Redundante? ¿Qué se repite? –

+0

Los argumentos que se pasan ya son locales para ese alcance. Los renombró 'arg0' y' arg1' y los reasignó sin ningún motivo. Ver mi código para aclaración. – Maverick

1

El cierre es creado por los parametros del constructor, así que esto es todo lo que necesita hacer (editado código de AlienWebguy):

var Person = function(name, age){ 

    this.getName = function() { 
     return name; 
    }; 

    this.getAge = function() { 
     return age; 
    }; 

}; 

var john = new Person('johnathan', 33); 

document.writeln(john.name);  // undefined 
document.writeln(john.age);   // undefined 
document.writeln(john.getName()); // johnathan 
document.writeln(john.getAge()); // 33 
+1

+1 Eliminé mi respuesta, esta es mucho mejor si el OP no quiere ningún setter. – AlienWebguy

+0

¿Por qué esto se bajó? – Maverick

+1

Buena pregunta .. – AlienWebguy

Cuestiones relacionadas