interfaz clases javascript typescript

javascript - clases - Miembros privados de TypeScript



interface typescript (6)

Estoy viendo la implementación de miembros privados en TypeScript, y me parece un poco confuso. Intellisense no permite acceder a miembros privados, pero en JavaScript puro, está todo allí. Esto me hace pensar que TS no implementa miembros privados correctamente. ¿Alguna idea?

class Test{ private member: any = "private member"; } alert(new Test().member);


Al igual que con la verificación de tipos, la privacidad de los miembros solo se aplica dentro del compilador.

Una propiedad privada se implementa como una propiedad regular, y el código fuera de la clase no tiene permiso para acceder a ella.

Para hacer algo realmente privado dentro de la clase, no puede ser un miembro de la clase, sería una variable local creada dentro de un alcance de función dentro del código que crea el objeto. Eso significaría que no puede acceder a él como un miembro de la clase, es decir, usando la palabra clave this .


En TypeScript, las funciones privadas solo son accesibles dentro de la clase. Me gusta

Y mostrará un error cuando intente acceder a un miembro privado. Aquí está el ejemplo:

Nota: estará bien con javascript y ambas funciones son accesibles desde el exterior.


Gracias a Sean Feldman por el enlace a la discusión oficial sobre este tema - vea su respuesta para el enlace.

Leí la discusión a la que él se vinculaba, y aquí hay un resumen de los puntos clave:

  • Sugerencia: propiedades privadas en constructor
    • problemas: no se puede acceder desde funciones prototipo
  • Sugerencia: métodos privados en constructor
    • problemas: igual que con las propiedades, además de perder el beneficio de rendimiento de crear una función una vez por clase en el prototipo; en su lugar, crea una copia de la función para cada instancia
  • Sugerencia: agregue texto estándar para acceder a propiedades abstractas y aplicar visibilidad
    • problemas: gastos generales importantes de rendimiento; TypeScript está diseñado para grandes aplicaciones
  • Sugerencia: TypeScript ya ajusta las definiciones de los métodos de constructor y prototipo en un cierre; poner métodos privados y propiedades allí
    • problemas para colocar propiedades privadas en ese cierre: se convierten en variables estáticas; no hay uno por instancia
    • problemas con poner métodos privados en ese cierre: no tienen acceso a this sin algún tipo de solución
  • Sugerencia: destruye automáticamente los nombres de las variables privadas
    • Contraargumentos: es una convención de nomenclatura, no una construcción de lenguaje. Destrúyelo tú mismo
  • Sugerencia: @private los métodos privados con @private para que los @private reconozcan que la anotación puede @private manera efectiva los nombres de los métodos
    • Sin contraarmas significativos para este

Contraargumentos generales para agregar soporte de visibilidad en el código emitido:

  • el problema es que el JavaScript en sí no tiene modificadores de visibilidad; este no es el problema de TypeScript
  • ya existe un patrón establecido en la comunidad JavaScript: prefijo propiedades privadas y métodos con un guión bajo, que dice "proceda bajo su propio riesgo"
  • cuando los diseñadores de TypeScript dijeron que las propiedades y métodos verdaderamente privados no son "posibles", querían decir "no son posibles bajo nuestras limitaciones de diseño", específicamente:
    • El JS emitido es idiomático
    • El texto repetitivo es mínimo
    • Sin sobrecarga adicional en comparación con JS OOP normal

JavaScript admite variables privadas.

function MyClass() { var myPrivateVar = 3; this.doSomething = function() { return myPrivateVar++; } }

En TypeScript esto se expresaría así:

class MyClass { doSomething: () => number; constructor() { var myPrivateVar = 3; this.doSomething = function () { return myPrivateVar++; } } }

EDITAR

Este enfoque solo se debe utilizar EN TODO donde sea absolutamente necesario. Por ejemplo, si necesita almacenar en caché una contraseña temporalmente.

El uso de este patrón tiene un costo de rendimiento (sin tener en cuenta Javascript o Typescript) y solo debe usarse donde sea absolutamente necesario.


Muchas personas afirman que esto no es posible debido a las limitaciones en JavaScript. Diría que son limitaciones en la creatividad de los desarrolladores de JavaScript.

Estoy desarrollando una biblioteca ahora que permite miembros de clases heredables, protegidos y privados, así como interfaces, etc., llamados ClassJS. Compruébalo aquí en github.com/KthProg/ClassJS .


Una vez que el soporte para WeakMap está más ampliamente disponible, hay una técnica interesante detallada en el ejemplo # 3 here .

Permite datos privados Y evita los costos de rendimiento del ejemplo de Jason Evans al permitir que los datos sean accesibles a partir de métodos prototipo en lugar de solo métodos de instancia.

La página enlazada MDN WeakMap enumera el soporte del navegador en Chrome 36, Firefox 6.0, IE 11, Opera 23 y Safari 7.1.

let _counter = new WeakMap(); let _action = new WeakMap(); class Countdown { constructor(counter, action) { _counter.set(this, counter); _action.set(this, action); } decrement() { let counter = _counter.get(this); if (counter < 1) return; counter--; _counter.set(this, counter); if (counter === 0) { _action.get(this)(); } } }