ero interessato a trovare un modo per rispondere alla tua domanda, ed ecco cosa sono stato in grado di fare.
Avrete bisogno di questo helper:
var ProtectedHandler = (function() {
/// <Sumarry>
/// Tool to handle the protected members of each inheritance.
/// </Summary>
/// <param name="current">Current protected variable.</param>
/// <param name="args">The arguments variable of the object.</param>
/// <param name="callback">The function to initialise the variable in the 'object'.</param>
/// <param name="isParent">Is this the ultimate base object.</param>
function ProtectedHandler(current, args, callback, isParent) {
this.child = getChild(args);
if (callback)
this.callback = callback;
if (isParent)
this.overrideChild(current);
}
// Get the ProtectedHandler from the arguments
var getChild = function (args) {
var child = null;
if (args.length > 0 && (child = args[args.length - 1]) && child.constructor === ProtectedHandler)
return child;
};
// Chain Initialise the protected variable of the object and its inheritances.
ProtectedHandler.prototype.overrideChild = function (newValue) {
if (this.callback != null) {
this.callback(newValue);
}
if (this.child != null) {
this.child.overrideChild(newValue);
}
};
// Static function to create a new instance of the protectedHandler object.
ProtectedHandler.handle = function (protected, arguments, callback, isParent) {
return new ProtectedHandler(protected, arguments, callback, isParent);
};
return ProtectedHandler;
})();
questo helper vi permetterà di gestire più eredità. Il trucco è copiare la variabile protetta dall'oggetto base al nuovo oggetto (figlio).
per dimostrare che si sta lavorando, ecco un esempio:
// That's the default extends function from typescript (ref: http://www.typescriptlang.org/)
var __extends = this.__extends || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var BaseClass = (function() {
function BaseClass() {
// Members
var private = {},
protected = {},
public = this;
// Constructor
ProtectedHandler.handle(protected, arguments, function() {
protected.type = "BaseClass";
}, true);
// Methods
protected.saySomething = function() {
return "Hello World";
};
public.getType = function() {
return protected.type;
};
}
return BaseClass;
})();
var Person = (function (_super) {
__extends(Person, _super);
function Person(name) {
// Members
var private = {},
protected = {},
public;
// Constructor
_super.call(public = this, ProtectedHandler.handle(protected, arguments, function (p) {
protected = p; //This is required to copy the object from its base object.
protected.name = name;
protected.type = "Person";
}));
//Method
public.getName = function() {
return protected.name;
};
public.saySomething = function() {
return protected.saySomething();
};
}
return Person;
})(BaseClass);
var Child = (function (_super) {
__extends(Child, _super);
function Child(name) {
// Members
var private = {},
protected = {},
public;
// Constructor
_super.call(public = this, name, ProtectedHandler.handle(protected, arguments, function (p) {
protected = p; //This is required to copy the object from its base object.
protected.type = "Child";
}));
//Method
public.setName = function (value) {
return protected.name = value;
};
}
return Child;
})(Person);
E 'qui il test:
var testBase = new BaseClass();
testBase.getType(); //"BaseClass"
testBase.saySomething; //undefined
var testPerson = new Person("Nic");
testPerson.getType(); //"Person"
testPerson.saySomething(); //"Hello World"
testPerson.name; //undefined
testPerson.getName() //"Nic"
testPerson.setName; //undefined
var testChild = new Child("Bob");
testChild.getType(); //"Child"
testChild.saySomething(); //"Hello World"
testChild.name; //undefined
testChild.getName(); //"Bob"
testChild.setName("George");
testChild.getName(); //"George"
No ............ –
Il mio consiglio, come spesso, è di non forzare la visibilità in JavaScript. * Alcune cose * sono possibili con chiusura, ecc, ma la lingua non è progettata per questo. Renderà il tuo codice più complesso. Invece, documenta i tuoi metodi correttamente come privati o pubblici e se altri sviluppatori non seguono le tue specifiche, è il loro problema. –
Btw, gli oggetti prototipo possono essere aumentati (non sono sigillati) - nulla impedisce a un intruso di aggiungere nuovi metodi all'oggetto prototipo. Quindi, avere una proprietà accessibile solo tramite metodi prototipo non sarebbe comunque sicuro (anche se fosse possibile). –