ejemplo javascript oop private-methods

ejemplo - Métodos privados de JavaScript



getelementbyid javascript ejemplo (29)

Para hacer una clase de JavaScript con un método público haría algo como:

function Restaurant() {} Restaurant.prototype.buy_food = function(){ // something here } Restaurant.prototype.use_restroom = function(){ // something here }

De esa manera los usuarios de mi clase pueden:

var restaurant = new Restaurant(); restaurant.buy_food(); restaurant.use_restroom();

¿Cómo creo un método privado al que pueden llamar los métodos buy_food y use_restroom pero no externamente por los usuarios de la clase?

En otras palabras, quiero que la implementación de mi método sea capaz de hacer:

Restaurant.prototype.use_restroom = function() { this.private_stuff(); }

Pero esto no debería funcionar:

var r = new Restaurant(); r.private_stuff();

¿Cómo defino private_stuff como un método privado para que ambos sean verdaderos?

He leído el artículo de Doug Crockford un par de veces, pero no parece que los métodos "privados" puedan ser llamados por métodos públicos y los métodos "privilegiados" pueden ser llamados externamente.


Usando la función de auto-invocación y la llamada

JavaScript usa prototypes y no tiene clases (o métodos para esa materia) como lenguajes orientados a objetos. Un desarrollador de JavaScript necesita pensar en JavaScript.

Cita de Wikipedia:

A diferencia de muchos lenguajes orientados a objetos, no hay distinción entre una definición de función y una definición de método. Más bien, la distinción se produce durante la llamada de función; cuando se llama a una función como método de un objeto, la palabra clave local de la función está vinculada a ese objeto para esa invocación.

Solución que utiliza una función de invocación automática y la función de llamada para llamar al "método" privado:

var MyObject = (function () { // Constructor function MyObject (foo) { this._foo = foo; } function privateFun (prefix) { return prefix + this._foo; } MyObject.prototype.publicFun = function () { return privateFun.call(this, ''>>''); } return MyObject; })(); var myObject = new MyObject(''bar''); myObject.publicFun(); // Returns ''>>bar'' myObject.privateFun(''>>''); // ReferenceError: private is not defined

La función de llamada nos permite llamar a la función privada con el contexto apropiado ( this ).


Más simple con Node.js

Si está utilizando node.js , no necesita el IIFE porque puede aprovechar el sistema de carga del módulo :

function MyObject (foo) { this._foo = foo; } function privateFun (prefix) { return prefix + this._foo; } MyObject.prototype.publicFun = function () { return privateFun.call(this, ''>>''); } exports.MyObject = MyObject;

Cargar el archivo:

var MyObject = require(''./MyObject'').MyObject; var myObject = new MyObject(''bar''); myObject.publicFun(); // Returns ''>>bar'' myObject.privateFun(''>>''); // ReferenceError: private is not defined


(experimental) ES7 con el Operador Bind

El operador de vinculación :: es una proposal ECMAScript y se implementa en Babel ( etapa 0 ).

export default class MyObject { constructor (foo) { this._foo = foo; } publicFun () { return this::privateFun(''>>''); } } function privateFun (prefix) { return prefix + this._foo; }

Cargar el archivo:

import MyObject from ''./MyObject''; let myObject = new MyObject(''bar''); myObject.publicFun(); // Returns ''>>bar'' myObject.privateFun(''>>''); // TypeError: myObject.privateFun is not a function


Aquí está la clase que creé para entender lo que Douglas Crockford ha sugerido en su sitio Miembros privados en JavaScript

function Employee(id, name) { //Constructor //Public member variables this.id = id; this.name = name; //Private member variables var fName; var lName; var that = this; //By convention, we create a private variable ''that''. This is used to //make the object available to the private methods. //Private function function setFName(pfname) { fName = pfname; alert(''setFName called''); } //Privileged function this.setLName = function (plName, pfname) { lName = plName; //Has access to private variables setFName(pfname); //Has access to private function alert(''setLName called '' + this.id); //Has access to member variables } //Another privileged member has access to both member variables and private variables //Note access of this.dataOfBirth created by public member setDateOfBirth this.toString = function () { return ''toString called '' + this.id + '' '' + this.name + '' '' + fName + '' '' + lName + '' '' + this.dataOfBirth; } } //Public function has access to member variable and can create on too but does not have access to private variable Employee.prototype.setDateOfBirth = function (dob) { alert(''setDateOfBirth called '' + this.id); this.dataOfBirth = dob; //Creates new public member note this is accessed by toString //alert(fName); //Does not have access to private member } $(document).ready() { var employee = new Employee(5, ''Shyam''); //Create a new object and initialize it with constructor employee.setLName(''Bhaskar'', ''Ram''); //Call privileged function employee.setDateOfBirth(''1/1/2000''); //Call public function employee.id = 9; //Set up member value //employee.setFName(''Ram''); //can not call Private Privileged method alert(employee.toString()); //See the changed object }


Como todo el mundo publicaba aquí su propio código, también lo haré ...

Me gusta Crockford porque introdujo patrones reales orientados a objetos en Javascript. Pero también se le ocurrió un nuevo malentendido, el "ese".

Entonces, ¿por qué usa "that = this"? No tiene nada que ver con funciones privadas en absoluto. ¡Tiene que ver con funciones internas!

Porque según Crockford este es un código de buggy:

Function Foo( ) { this.bar = 0; var foobar=function( ) { alert(this.bar); } }

Así que sugirió hacer esto:

Function Foo( ) { this.bar = 0; that = this; var foobar=function( ) { alert(that.bar); } }

Entonces, como dije, estoy bastante seguro de que Crockford se equivocó al explicar esto y esto (pero su código es ciertamente correcto) ¿O simplemente estaba engañando al mundo de Javascript, para saber quién está copiando su código? No lo sé ... No soy un geek del navegador; D

EDITAR

Ah, de eso se trata: ¿Qué significa ''var that = this;'' significa en JavaScript?

Así que Crockie estaba realmente equivocado con su explicación ... pero correcto con su código, por lo que sigue siendo un gran tipo. :))


Conjuré esto: EDITAR: En realidad, alguien se ha vinculado a una solución idéntica. Duh!

var Car = function() { } Car.prototype = (function() { var hotWire = function() { // Private code *with* access to public properties through ''this'' alert( this.drive() ); // Alerts ''Vroom!'' } return { steal: function() { hotWire.call( this ); // Call a private method }, drive: function() { return ''Vroom!''; } }; })(); var getAwayVechile = new Car(); hotWire(); // Not allowed getAwayVechile.hotWire(); // Not allowed getAwayVechile.steal(); // Alerts ''Vroom!''


Creo que estas preguntas surgen una y otra vez debido a la falta de comprensión de los cierres. Los seguros es lo más importante en JS. Cada programador de JS tiene que sentir la esencia de ello.

1. En primer lugar tenemos que hacer un alcance separado (cierre).

function () { }

2. En esta área, podemos hacer lo que queramos. Y nadie lo sabrá.

function () { var name, secretSkills = { pizza: function () { return new Pizza() }, sushi: function () { return new Sushi() } } function Restaurant(_name) { name = _name } Restaurant.prototype.getFood = function (name) { return name in secretSkills ? secretSkills[name]() : null } }

3. Para que el mundo sepa sobre nuestra clase de restaurante, tenemos que devolverlo desde el cierre.

var Restaurant = (function () { // Restaurant definition return Restaurant })()

4. Al final, tenemos:

var Restaurant = (function () { var name, secretSkills = { pizza: function () { return new Pizza() }, sushi: function () { return new Sushi() } } function Restaurant(_name) { name = _name } Restaurant.prototype.getFood = function (name) { return name in secretSkills ? secretSkills[name]() : null } return Restaurant })()

5. Además, este enfoque tiene potencial para herencia y plantillas

// Abstract class function AbstractRestaurant(skills) { var name function Restaurant(_name) { name = _name } Restaurant.prototype.getFood = function (name) { return skills && name in skills ? skills[name]() : null } return Restaurant } // Concrete classes SushiRestaurant = AbstractRestaurant({ sushi: function() { return new Sushi() } }) PizzaRestaurant = AbstractRestaurant({ pizza: function() { return new Pizza() } }) var r1 = new SushiRestaurant(''Yo! Sushi''), r2 = new PizzaRestaurant(''Dominos Pizza'') r1.getFood(''sushi'') r2.getFood(''pizza'')

Espero que esto ayude a alguien a entender mejor este tema.


El patrón del módulo es correcto en la mayoría de los casos. Pero si tienes miles de instancias, las clases ahorran memoria. Si ahorrar memoria es una preocupación y sus objetos contienen una pequeña cantidad de datos privados, pero tienen muchas funciones públicas, querrá que todas las funciones públicas vivan en el prototipo para ahorrar memoria.

Esto es lo que se me ocurrió:

var MyClass = (function () { var secret = {}; // You can only getPriv() if you know this function MyClass() { var that = this, priv = { foo: 0 // ... and other private values }; that.getPriv = function (proof) { return (proof === secret) && priv; }; } MyClass.prototype.inc = function () { var priv = this.getPriv(secret); priv.foo += 1; return priv.foo; }; return MyClass; }()); var x = new MyClass(); x.inc(); // 1 x.inc(); // 2

El objeto priv contiene propiedades privadas. Es accesible a través de la función pública getPriv() , pero esta función devuelve false menos que le pases el secret , y esto solo se conoce dentro del cierre principal.


En estas situaciones, cuando tiene una API pública y desea métodos / propiedades privadas y públicas, siempre uso el Patrón del Módulo. Este patrón se hizo popular dentro de la biblioteca YUI, y los detalles se pueden encontrar aquí:

http://yuiblog.com/blog/2007/06/12/module-pattern/

Es realmente sencillo y fácil de comprender para otros desarrolladores. Para un ejemplo simple:

var MYLIB = function() { var aPrivateProperty = true; var aPrivateMethod = function() { // some code here... }; return { aPublicMethod : function() { aPrivateMethod(); // okay // some code here... }, aPublicProperty : true }; }(); MYLIB.aPrivateMethod() // not okay MYLIB.aPublicMethod() // okay


Envuelva todo el código en la Función anónima: Entonces, todas las funciones serán privadas, SOLO funciones adjuntas al objeto de la window :

(function(w,nameSpacePrivate){ w.Person=function(name){ this.name=name; return this; }; w.Person.prototype.profilePublic=function(){ return nameSpacePrivate.profile.call(this); }; nameSpacePrivate.profile=function(){ return ''My name is ''+this.name; }; })(window,{});

Utilizar esta :

var abdennour=new Person(''Abdennour''); abdennour.profilePublic();

FIDDLE


Esto es lo que más he disfrutado hasta ahora con respecto a los métodos / miembros privados / públicos y la creación de instancias en javascript:

Aquí está el artículo: http://www.sefol.com/?p=1090

Y aquí está el ejemplo:

var Person = (function () { //Immediately returns an anonymous function which builds our modules return function (name, location) { alert("createPerson called with " + name); var localPrivateVar = name; var localPublicVar = "A public variable"; var localPublicFunction = function () { alert("PUBLIC Func called, private var is :" + localPrivateVar) }; var localPrivateFunction = function () { alert("PRIVATE Func called ") }; var setName = function (name) { localPrivateVar = name; } return { publicVar: localPublicVar, location: location, publicFunction: localPublicFunction, setName: setName } } })(); //Request a Person instance - should print "createPerson called with ben" var x = Person("ben", "germany"); //Request a Person instance - should print "createPerson called with candide" var y = Person("candide", "belgium"); //Prints "ben" x.publicFunction(); //Prints "candide" y.publicFunction(); //Now call a public function which sets the value of a private variable in the x instance x.setName("Ben 2"); //Shouldn''t have changed this : prints "candide" y.publicFunction(); //Should have changed this : prints "Ben 2" x.publicFunction();

JSFiddle: http://jsfiddle.net/northkildonan/kopj3dt3/1/



Las funciones privadas no pueden acceder a las variables públicas usando el patrón del módulo


Personalmente, prefiero el siguiente patrón para crear clases en JavaScript:

var myClass = (function() { // Private class properties go here var blueprint = function() { // Private instance properties go here ... }; blueprint.prototype = { // Public class properties go here ... }; return { // Public class properties go here create : function() { return new blueprint(); } ... }; })();

Como puede ver, le permite definir propiedades de clase y propiedades de instancia, cada una de las cuales puede ser pública y privada.

Manifestación

var Restaurant = function() { var totalfoodcount = 0; // Private class property var totalrestroomcount = 0; // Private class property var Restaurant = function(name){ var foodcount = 0; // Private instance property var restroomcount = 0; // Private instance property this.name = name this.incrementFoodCount = function() { foodcount++; totalfoodcount++; this.printStatus(); }; this.incrementRestroomCount = function() { restroomcount++; totalrestroomcount++; this.printStatus(); }; this.getRestroomCount = function() { return restroomcount; }, this.getFoodCount = function() { return foodcount; } }; Restaurant.prototype = { name : '''', buy_food : function(){ this.incrementFoodCount(); }, use_restroom : function(){ this.incrementRestroomCount(); }, getTotalRestroomCount : function() { return totalrestroomcount; }, getTotalFoodCount : function() { return totalfoodcount; }, printStatus : function() { document.body.innerHTML += ''<h3>Buying food at ''+this.name+''</h3>'' + ''<ul>'' + ''<li>Restroom count at '' + this.name + '' : ''+ this.getRestroomCount() + ''</li>'' + ''<li>Food count at '' + this.name + '' : '' + this.getFoodCount() + ''</li>'' + ''<li>Total restroom count : ''+ this.getTotalRestroomCount() + ''</li>'' + ''<li>Total food count : ''+ this.getTotalFoodCount() + ''</li>'' + ''</ul>''; } }; return { // Singleton public properties create : function(name) { return new Restaurant(name); }, printStatus : function() { document.body.innerHTML += ''<hr />'' + ''<h3>Overview</h3>'' + ''<ul>'' + ''<li>Total restroom count : ''+ Restaurant.prototype.getTotalRestroomCount() + ''</li>'' + ''<li>Total food count : ''+ Restaurant.prototype.getTotalFoodCount() + ''</li>'' + ''</ul>'' + ''<hr />''; } }; }(); var Wendys = Restaurant.create("Wendy''s"); var McDonalds = Restaurant.create("McDonald''s"); var KFC = Restaurant.create("KFC"); var BurgerKing = Restaurant.create("Burger King"); Restaurant.printStatus(); Wendys.buy_food(); Wendys.use_restroom(); KFC.use_restroom(); KFC.use_restroom(); Wendys.use_restroom(); McDonalds.buy_food(); BurgerKing.buy_food(); Restaurant.printStatus(); BurgerKing.buy_food(); Wendys.use_restroom(); McDonalds.buy_food(); KFC.buy_food(); Wendys.buy_food(); BurgerKing.buy_food(); McDonalds.buy_food(); Restaurant.printStatus();

Véase también este violín .


Puedes hacerlo, pero el inconveniente es que no puede ser parte del prototipo:

function Restaurant() { var myPrivateVar; var private_stuff = function() // Only visible inside Restaurant() { myPrivateVar = "I can set this here!"; } this.use_restroom = function() // use_restroom is visible to all { private_stuff(); } this.buy_food = function() // buy_food is visible to all { private_stuff(); } }


Puedes simular métodos privados como este:

function Restaurant() { } Restaurant.prototype = (function() { var private_stuff = function() { // Private code here }; return { constructor:Restaurant, use_restroom:function() { private_stuff(); } }; })(); var r = new Restaurant(); // This will work: r.use_restroom(); // This will cause an error: r.private_stuff();

Más información sobre esta técnica aquí: http://webreflection.blogspot.com/2008/04/natural-javascript-private-methods.html


Que hay de esto

var Restaurant = (function() { var _id = 0; var privateVars = []; function Restaurant(name) { this.id = ++_id; this.name = name; privateVars[this.id] = { cooked: [] }; } Restaurant.prototype.cook = function (food) { privateVars[this.id].cooked.push(food); } return Restaurant; })();

La búsqueda de variables privadas es imposible fuera del alcance de la función inmediata. No hay duplicación de funciones, salvando memoria.

La desventaja es que la búsqueda de variables privadas es un tipo de privateVars[this.id].cooked es ridículo de escribir. También hay una variable adicional "id".


Si desea la gama completa de funciones públicas y privadas con la capacidad para que las funciones públicas accedan a funciones privadas, el código de diseño para un objeto como este:

function MyObject(arg1, arg2, ...) { //constructor code using constructor arguments... //create/access public variables as // this.var1 = foo; //private variables var v1; var v2; //private functions function privateOne() { } function privateTwon() { } //public functions MyObject.prototype.publicOne = function () { }; MyObject.prototype.publicTwo = function () { }; }


Todo este cierre te costará. Asegúrese de probar las implicaciones de la velocidad, especialmente en IE. Encontrarás que estás mejor con una convención de nomenclatura. Todavía hay muchos usuarios web corporativos que están obligados a usar IE6 ...


Tome cualquiera de las soluciones que siguen el patrón privado o privilegiado de Crockford. Por ejemplo:

function Foo(x) { var y = 5; var bar = function() { return y * x; }; this.public = function(z) { return bar() + x * z; }; }

En cualquier caso en el que el atacante no tenga "ejecución" en el contexto JS, no tiene forma de acceder a ningún campo o método "público" o "privado". En caso de que el atacante tenga ese acceso, puede ejecutar esta línea de una sola línea:

eval("Foo = " + Foo.toString().replace( /{/, "{ this.eval = function(code) { return eval(code); }; " ));

Tenga en cuenta que el código anterior es genérico para toda la privacidad de tipo constructor. Aquí fallarán algunas de las soluciones, pero debería quedar claro que casi todas las soluciones basadas en el cierre se pueden romper de esta manera con diferentes parámetros de replace() .

Después de que esto se ejecute, cualquier objeto creado con el new Foo() tendrá un método eval que se puede llamar para devolver o cambiar valores o métodos definidos en el cierre del constructor, por ejemplo:

f = new Foo(99); f.eval("x"); f.eval("y"); f.eval("x = 8");

El único problema que puedo ver con esto es que no funcionará en los casos en que solo hay una instancia y se crea en la carga. Pero entonces no hay razón para definir realmente un prototipo y, en ese caso, el atacante puede simplemente recrear el objeto en lugar del constructor siempre que tenga una forma de pasar los mismos parámetros (por ejemplo, son constantes o están calculados a partir de los valores disponibles).

En mi opinión, esto prácticamente hace que la solución de Crockford sea inútil. Dado que la "privacidad" se rompe fácilmente, las desventajas de su solución (menor legibilidad y mantenibilidad, menor rendimiento, mayor memoria) hacen que el método basado en el prototipo "sin privacidad" sea la mejor opción.

Por lo general, uso guiones bajos para marcar los métodos y campos de __private y _protected (estilo Perl), pero la idea de tener privacidad en JavaScript solo muestra cómo se trata de un lenguaje incomprendido.

Por lo tanto, no estoy de acuerdo con Crockford a excepción de su primera oración.

Entonces, ¿cómo se obtiene la privacidad real en JS? Coloque todo lo que se requiere para ser privado en el lado del servidor y use JS para hacer llamadas AJAX.


Esto es lo que resolví:

Necesita una clase de código de azúcar que puede encontrar aquí . También soporta material protegido, herencia, virtual, estático ...

;( function class_Restaurant( namespace ) { ''use strict''; if( namespace[ "Restaurant" ] ) return // protect against double inclusions namespace.Restaurant = Restaurant var Static = TidBits.OoJs.setupClass( namespace, "Restaurant" ) // constructor // function Restaurant() { this.toilets = 3 this.Private( private_stuff ) return this.Public( buy_food, use_restroom ) } function private_stuff(){ console.log( "There are", this.toilets, "toilets available") } function buy_food (){ return "food" } function use_restroom (){ this.private_stuff() } })( window ) var chinese = new Restaurant console.log( chinese.buy_food() ); // output: food console.log( chinese.use_restroom() ); // output: There are 3 toilets available console.log( chinese.toilets ); // output: undefined console.log( chinese.private_stuff() ); // output: undefined // and throws: TypeError: Object #<Restaurant> has no method ''private_stuff''


Sé que es un poco tarde, pero ¿qué tal esto?

var obj = function(){ var pr = "private"; var prt = Object.getPrototypeOf(this); if(!prt.hasOwnProperty("showPrivate")){ prt.showPrivate = function(){ console.log(pr); } } } var i = new obj(); i.showPrivate(); console.log(i.hasOwnProperty("pr"));


En general agregué el objeto privado _ temporalmente al objeto. Tienes que abrir la privacidad de forma exagerada en el "Power-constructor" para el método. Si llama al método desde el prototipo, podrá sobrescribir el método prototipo.

  • Hacer un método público accesible en el "Power-constructor": (ctx es el contexto del objeto)

    ctx.test = GD.Fabric.open(''test'', GD.Test.prototype, ctx, _); // is a private object

  • Ahora tengo este openPrivacy:

    GD.Fabric.openPrivacy = function(func, clss, ctx, _) { return function() { ctx._ = _; var res = clss[func].apply(ctx, arguments); ctx._ = null; return res; }; };


He creado una nueva herramienta para permitirle tener verdaderos métodos privados en el prototipo https://github.com/TremayneChrist/ProtectJS

Ejemplo:

var MyObject = (function () { // Create the object function MyObject() {} // Add methods to the prototype MyObject.prototype = { // This is our public method public: function () { console.log(''PUBLIC method has been called''); }, // This is our private method, using (_) _private: function () { console.log(''PRIVATE method has been called''); } } return protect(MyObject); })(); // Create an instance of the object var mo = new MyObject(); // Call its methods mo.public(); // Pass mo._private(); // Fail


No seas tan detallado. Es Javascript. Utilice una convención de nomenclatura .

Después de años de trabajar en clases de es6, recientemente comencé a trabajar en un proyecto de es5 (utilizando requireJS que ya tiene un aspecto muy detallado). He examinado una y otra vez todas las estrategias mencionadas aquí y, básicamente, todo se reduce a usar una convención de nombres :

  1. Javascript no tiene palabras clave de alcance como private. Otros desarrolladores que ingresen a Javascript sabrán esto por adelantado. Por lo tanto, una simple convención de nomenclatura es más que suficiente. Una simple convención de nomenclatura de prefijo con un guión bajo resuelve el problema de las propiedades privadas y los métodos privados.
  2. Aprovechemos el Prototipo por razones de velocidad, pero no seamos más detallados que eso. Intentemos mantener la "clase" de es5 mirando lo más que podamos esperar en otros lenguajes backend (y tratemos cada archivo como una clase, incluso si no necesitamos devolver una instancia).
  3. Demostremos con una situación de módulo más realista (usaremos el es5 antiguo y el antiguo requireJs).

mi-tooltip.js

define([ ''tooltip'' ], function( tooltip ){ function MyTooltip() { // Later, if needed, we can remove the underscore on some // of these (make public) and allow clients of our class // to set them. this._selector = "#my-tooltip" this._template = ''Hello from inside my tooltip!''; this._initTooltip(); } MyTooltip.prototype = { constructor: MyTooltip, _initTooltip: function () { new tooltip.tooltip(this._selector, { content: this._template, closeOnClick: true, closeButton: true }); } } return { init: function init() { new MyTooltip(); // <-- Our constructor adds our tooltip to the DOM so not much we need to do after instantiation. } // You could instead return a new instantiation, // if later you do more with this class. /* create: function create() { return new MyTooltip(); } */ } });


Prefiero almacenar datos privados en un asociado WeakMap. Esto le permite mantener sus métodos públicos en el prototipo al que pertenecen. Esta parece ser la forma más eficiente de manejar este problema para una gran cantidad de objetos.

const data = new WeakMap(); function Foo(value) { data.set(this, {value}); } // public method accessing private value Foo.prototype.accessValue = function() { return data.get(this).value; } // private ''method'' accessing private value function accessValue(foo) { return data.get(foo).value; } export {Foo};


Tiene que poner un cierre alrededor de su función constructora real, donde puede definir sus métodos privados. Para cambiar los datos de las instancias a través de estos métodos privados, debe darles "esto" con ellos, ya sea como un argumento de función o llamando a esta función con .apply (this)

var Restaurant = (function(){ var private_buy_food = function(that){ that.data.soldFood = true; } var private_take_a_shit = function(){ this.data.isdirty = true; } // New Closure function restaurant() { this.data = { isdirty : false, soldFood: false, }; } restaurant.prototype.buy_food = function() { private_buy_food(this); } restaurant.prototype.use_restroom = function() { private_take_a_shit.call(this); } return restaurant; })() // TEST: var McDonalds = new Restaurant(); McDonalds.buy_food(); McDonalds.use_restroom(); console.log(McDonalds); console.log(McDonalds.__proto__);


Vea esta respuesta para una solución de "clase" limpia y simple con una interfaz privada y pública y soporte para composición


Ya hay muchas respuestas a esta pregunta, pero nada se ajusta a mis necesidades. Entonces se me ocurrió mi propia solución, espero que sea útil para alguien:

function calledPrivate(){ var stack = new Error().stack.toString().split("/n"); function getClass(line){ var i = line.indexOf(" "); var i2 = line.indexOf("."); return line.substring(i,i2); } return getClass(stack[2])==getClass(stack[3]); } class Obj{ privateMethode(){ if(calledPrivate()){ console.log("your code goes here"); } } publicMethode(){ this.privateMethode(); } } var obj = new Obj(); obj.publicMethode(); //logs "your code goes here" obj.privateMethode(); //does nothing

Como puede ver, este sistema funciona cuando se usa este tipo de clases en javascript. Hasta donde descubrí, ninguno de los métodos comentados anteriormente lo hizo.


Class({ Namespace:ABC, Name:"ClassL2", Bases:[ABC.ClassTop], Private:{ m_var:2 }, Protected:{ proval:2, fight:Property(function(){ this.m_var--; console.log("ClassL2::fight (m_var)" +this.m_var); },[Property.Type.Virtual]) }, Public:{ Fight:function(){ console.log("ClassL2::Fight (m_var)"+this.m_var); this.fight(); } } });

https://github.com/nooning/JSClass


var TestClass = function( ) { var privateProperty = 42; function privateMethod( ) { alert( "privateMethod, " + privateProperty ); } this.public = { constructor: TestClass, publicProperty: 88, publicMethod: function( ) { alert( "publicMethod" ); privateMethod( ); } }; }; TestClass.prototype = new TestClass( ).public; var myTestClass = new TestClass( ); alert( myTestClass.publicProperty ); myTestClass.publicMethod( ); alert( myTestClass.privateMethod || "no privateMethod" );

Similar a georgebrock pero un poco menos detallado (IMHO) ¿Tienes problemas para hacerlo de esta manera? (No lo he visto en ninguna parte)

Edición: Me di cuenta de que esto es un poco inútil, ya que cada instancia independiente tiene su propia copia de los métodos públicos, lo que socava el uso del prototipo.