Javascript反思

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"关键字,它们将被附加到全局上下文(通常是窗口对象),但这是我所知道的唯一与您所描述的类似的行为.但是,如果您这样做,那么该对象上会有很多其他属性和方法.


Jay*_*Jay 5

来自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)