Owe*_*wen 28 javascript reflection closures
有没有办法从内部获取javascript对象的所有方法(私有,特权或公共)?这是示例对象:
var Test = function() {
// private methods
function testOne() {}
function testTwo() {}
function testThree() {}
// public methods
function getMethods() {
for (i in this) {
alert(i); // shows getMethods, but not private methods
}
}
return { getMethods : getMethods }
}();
// should return ['testOne', 'testTwo', 'testThree', 'getMethods']
Test.getMethods();
Run Code Online (Sandbox Code Playgroud)
当前的问题是代码getMethods()
,简化示例将仅返回公共方法,但不返回私有方法.
编辑:我的测试代码可能(或可能不)过于复杂,我希望得到的.给出以下内容:
function myFunction() {
var test1 = 1;
var test2 = 2;
var test3 = 3;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法myFunction()
从内部找出存在的变量myFunction()
.伪代码看起来像这样:
function myFunction() {
var test1 = 1;
var test2 = 2;
var test3 = 3;
alert(current.properties); // would be nice to get ['test1', 'test2', 'test3']
}
Run Code Online (Sandbox Code Playgroud)
小智 28
隐藏这些方法的技术原因是双重的.
首先,当您在Test对象上执行方法时,"this"将是匿名函数末尾返回的无类型对象,该函数包含模块模式的公共方法.
其次,方法testOne,testTwo和testThree不附加到特定对象,并且仅存在于匿名函数的上下文中.您可以将方法附加到内部对象,然后通过公共方法公开它们,但它不会像原始模式那样干净,如果您从第三方获取此代码,它将无济于事.
结果看起来像这样:
var Test = function() {
var private = {
testOne : function () {},
testTwo : function () {},
testThree : function () {}
};
function getMethods() {
for (i in this) {
alert(i); // shows getMethods, but not private methods
}
for (i in private) {
alert(i); // private methods
}
}
return { getMethods : getMethods }
}();
// will return ['getMethods', 'testOne', 'testTwo', 'testThree']
Test.getMethods();
Run Code Online (Sandbox Code Playgroud)
编辑:
很不幸的是,不行.无法通过单个自动关键字访问本地变量集.
如果删除"var"关键字,它们将被附加到全局上下文(通常是窗口对象),但这是我所知道的唯一与您所描述的类似的行为.但是,如果您这样做,那么该对象上会有很多其他属性和方法.
来自http://netjs.codeplex.com/SourceControl/changeset/view/91169#1773642
//Reflection
~function (extern) {
var Reflection = this.Reflection = (function () { return Reflection; });
Reflection.prototype = Reflection;
Reflection.constructor = Reflection;
Reflection.getArguments = function (func) {
var symbols = func.toString(),
start, end, register;
start = symbols.indexOf('function');
if (start !== 0 && start !== 1) return undefined;
start = symbols.indexOf('(', start);
end = symbols.indexOf(')', start);
var args = [];
symbols.substr(start + 1, end - start - 1).split(',').forEach(function (argument) {
args.push(argument);
});
return args;
};
extern.Reflection = extern.reflection = Reflection;
Function.prototype.getArguments = function () { return Reflection.getArguments(this); }
Function.prototype.getExpectedReturnType = function () { /*ToDo*/ }
} (this);
Run Code Online (Sandbox Code Playgroud)