molily: OOP-Propertys mit Accessor

Beitrag lesen

Hallo,

Symbols wird es in ECMAScript 6 geben und würden dein Problem elegant lösen:

https://github.com/lukehoban/es6features#symbols
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-symbol-constructor-class

function setData(obj, data, names) {
Mir gefällt nicht sonderlich, dass sie global rumliegt. Anderseits, sie an Object.prototype anzuhängen, macht es nicht viel besser.

Richtig, deshalb gibt es Object.assign in ES6. Shim:
https://github.com/paulmillr/es6-shim/
https://github.com/ljharb/object.assign

function Foo(data) {
var self = {
name: ''
};

Ich würde die Variable nicht »self«, sondern z.B. »store«, »storage« oder »attributes« nennen, weil man üblicherweise var self = this; schreibt, also self eine Referenz auf die Instanz ist.

Object.defineProperties(this, {
Name: {
enumerable: true,
get: function () {
return self.name;
(…)
Unschön ist, dass die Property in jede Instanz (this) neu eingefügt wird.

Finde ich verschmerzbar. Nur so ist echte Privatheit zu erreichen.

Siehe Wozu Kapselung gut ist und wann sie nötig ist.

Nun sah ich, dass man heutzutage gar nicht mehr die Konstruktorfunktion so direkt definiert, weil sie dann global angelegt ist und sich nicht modularisieren lässt.

Das macht man durchaus noch, wenn es zielführend ist. Die zusätzliche IIFE benutzt man nur, wenn man einen privaten Scope braucht.

var Bar = (function () { … })();

Hier legst du letztlich auch eine globale Variable an bzw. eine Variable im entsprechenden Scope.

Dummerweise ist self in der kapselnden anonymen Funktion angesiedelt und da diese nur einmal existiert, existiert auch self nur einmal und nicht in jeder Objektinstanz separat.

Japp, das sollte man möglichst vermeiden.

Object.defineProperties(Qux.prototype, {…});

Preis ist aber, dass self nun öffentlich im Objekt zu sehen ist und nicht mehr privat ist. … Was wäre denn empfehlenswert?

Das ist eine Grundfrage von JavaScript, auf die ich in der oben verlinkten Doku auch eingehe:

Entweder man will effektive Privatheit, dann hilft nur die Closure, weil das in JS die einzige Möglichkeit ist, Sichtbarkeit zu regulieren.

Oder einem reichen pseudo-private Eigenschaften aus. Dann gibt es die Konvention, die Eigenschaften z.B. mit einem »_«-Präfix zu versehen und sie ggf. als non-enumerable und non-configurable zu markieren.

Ich halte beides für vertretbar. Pseudo-private Eigenschaften halte ich für ausreichend. Sie sind performanter hinsichtlich der Erzeugung von Instanzen, da Getter/Setter einmal am Prototyp definiert werden. Sie erlauben dem JS-Interpreter eine Optimierung mittels »Hidden Classes«. Und sie erlauben ein einfaches Debugging, da die Eigenschaft im Zweifelsfall von außen zugänglich ist.

Letztlich sind »private« Eigenschaften in vielen anderen Sprachen nicht wirklich privat. Siehe zum Hintergrund:
http://dmitrysoshnikov.com/ecmascript/chapter-7-1-oop-general-theory/#encapsulation

Mathias