8

我一直在研究 JavaScript 中反射的可能性。我已经有一个简单的反射器,可以列出对象/函数的成员,如下所示:

window["Foo"] = {
    "Bar": {
        "Test": function () {
            this.x = 32;
            this._hello = "Hello World";
            this._item = 123.345;

            this.hello = function() {
                alert("hello");
            };

            this.goodbye = function() {
                alert("goodbye");
            }
        }
    }
}

$(document).ready(function () {
    var x = new Foo.Bar.Test();
    Reflect(new Foo.Bar.Test());
});

function Reflect(obj) {
    for (var item in obj) {
        $("body").append(item + "(" + typeof obj[item] + ") = " + obj[item] + "<br />");
    }
}

结果:

x(数字) = 32

_hello(string) = 你好世界

_item(number) = 123.345

你好(函数)=函数(){警报(“你好”);}

再见(函数)=函数(){警报(“再见”);}

我挑战的下一部分是构建可以反映(如果可能)对象名称和对象路径的东西。

使用这个例子:...

var x = new Foo.Bar.Test();

如何从 x 反映“测试”?例如:

ReflectName(x); //returns "Test";

另外我怎样才能反映到x的路径?例如:

ReflectPath(x) //returns Foo.Bar.Test

是否可以使用 JavaScript 完成这两件事?我对此进行了研究,到目前为止还没有设法提出任何可行的解决方案。

我不想要一个需要硬编码对象/函数的名称和路径的解决方案,因为这会破坏使用反射的意义。

4

3 回答 3

13

JavaScript 中没有类(尽管由于我不知道的原因模仿 Java 的代码风格,你可能认为有一些)。 Foo.Bar.Test不是指Test在命名空间中注册的类Foo.Bar,而是指作为某个对象的属性分配的函数,该Test对象被分配为某个对象的属性Bar,称为Foo.

您不能像“给我7分配了数字的所有变量”那样进行反思,因此您不能列出所有包含Test其属性之一的对象。

这实际上很好并且开辟了新的可能性,但一开始可能会令人困惑。

顺便说一句,由于 JavaScript 中没有类,我相信术语反射不是很幸运。new Foo()并不是说“创建 Foo 的新实例”,而是“创建一个新对象并在该对象的上下文中执行函数,Foo最后返回它。是的new,如果你想在 JavaScript 中做更高级的事情,这个关键字很混乱, 永远不要相信你的 Java/C# 经验。JavaScript 伪造 Java(我想不会吓到新手并让他们快速做简单的事情),但它非常不同。

于 2012-12-17T10:23:28.310 回答
5

这在 JavaScript 中是不可能的。(为了更深入地了解 JavaScript 的类型系统,我推荐阅读这篇文章。)

您可以做的最好的近似是查询静态JSON 结构

于 2012-12-17T10:39:33.583 回答
2

回答你的第一个问题

function ReflectName(obj) { return obj.__proto__.constructor.name }

第二个问题有点困难,需要对定义进行更多设置。

这里的回答要好一些:Javascript objects: get parent

于 2017-11-23T03:22:34.787 回答