Im Framework, das ich entwickle, habe ich einen Mechanismus konstruiert, der es erlaubt, private und geschützte Eigenschaften und Methoden zu definieren.
Die einzige Möglichkeit, die ich in den ES5-Spezifikationen gefunden habe, um das zu tun, war die Verwendung von arguments.callee
so:
descriptor.method = function () {
if (__callerIsProptected(arguments.callee.caller.caller, cls))
return value.apply(this, __defaults(_.values(arguments), defaults));
throw 'Versuch, die ' + access + ' Methode "' + cls._name + '::' + name + '" aufzurufen';
};
In Strict-Modus rufen Aufrufe von arguments.callee und arguments.caller Ausnahmen hervor. Gibt es bequeme Alternativen, um das zu tun?
Aktualisierung - hinzugefügter gesamter Funktionscode
function __descriptor(cls, type, name, descriptor, access) {
//protected private non-function descriptor.value is replaced by get/set pair
if (access !== 'public' && type == 'property') {
delete descriptor.value;
delete descriptor.writable;
_.isFunction(descriptor.get) || (descriptor.get = function () {
return this.__get(name);
});
_.isFunction(descriptor.set) || (descriptor.set = function (value) {
return this.__set(name, value);
});
}
//remove uselesses
if (_.isFunction(descriptor.get) || _.isFunction(descriptor.set)) {
delete descriptor.value;
delete descriptor.writable;
if (!_.isFunction(descriptor.get)) {
descriptor.get = function () {
return this.__get(name);
};
}
if (!_.isFunction(descriptor.set)) {
descriptor.set = function (value) {
return this.__set(name, value);
};
}
} else {
delete descriptor.get;
delete descriptor.set;
}
if (descriptor.get) {
var getter = descriptor.get;
//mutate getter and setter if given respectively to access level
if (access === 'public') {
descriptor.getter = function () {
return getter.apply(this, arguments);
};
} else if (access === 'protected') {
descriptor.getter = function () {
if (__callerIsProptected(arguments.callee.caller.caller, cls))
return getter.apply(this, arguments);
throw 'Versuch, das ' + access + ' Eigenschaft "' + cls._name + '::' + name + '"';
};
} else if (access === 'private') {
descriptor.getter = function () {
if (__callerIsPrivate(arguments.callee.caller.caller, cls))
return getter.apply(this, arguments);
throw 'Versuch, das ' + access + ' Eigenschaft "' + cls._name + '::' + name + '"';
};
}
descriptor.getter._class = cls;
}
if (descriptor.set) {
var setter = descriptor.set;
//mutate getter and setter if given respectively to access level
if (access === 'public') {
descriptor.setter = function () {
return setter.apply(this, arguments);
};
} else if (access === 'protected') {
descriptor.setter = function () {
if (__callerIsProptected(arguments.callee.caller.caller, cls))
return setter.apply(this, arguments);
throw 'Versuch, das ' + access + ' Eigenschaft "' + cls._name + '::' + name + '"';
};
} else if (access === 'private') {
descriptor.setter = function () {
if (__callerIsPrivate(arguments.callee.caller.caller, cls))
return setter.apply(this, arguments);
throw 'Versuch, das ' + access + ' Eigenschaft "' + cls._name + '::' + name + '"';
};
}
descriptor.setter._class = cls;
}
if (descriptor.value !== undefined) {
if (!_.isFunction(descriptor.value)) return descriptor;
var value = descriptor.value;
var defaults = descriptor.defaults || [];
if (access === 'public' && type == 'method') {
descriptor.method = function () {
return value.apply(this, __defaults(_.values(arguments), defaults));
};
} else if (access === 'protected') {
descriptor.method = function () {
if (__callerIsProptected(arguments.callee.caller.caller, cls))
return value.apply(this, __defaults(_.values(arguments), defaults));
throw 'Versuch, die ' + access + ' Methode "' + cls._name + '::' + name + '"';
};
} else if (access === 'private') {
descriptor.method = function () {
if (__callerIsPrivate(arguments.callee.caller.caller, cls))
return value.apply(this, __defaults(_.values(arguments), defaults));
throw 'Versuch, die ' + access + ' Methode "' + cls._name + '::' + name + '"';
};
}
descriptor.method._class = cls;
}
return descriptor;
}