JavaScript 中的反射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13910962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reflection in JavaScript
提问by Matthew Layton
I have been looking into the possibility of reflection in JavaScript. I already have a simple reflector which can list the members of an object/function, like so:
我一直在研究 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 />");
}
}
Results:
结果:
x(number) = 32
_hello(string) = Hello World
_item(number) = 123.345
hello(function) = function () { alert("hello"); }
goodbye(function) = function () { alert("goodbye"); }
x(数) = 32
_hello(string) = 你好世界
_项目(数量)= 123.345
你好(函数)= 函数(){ 警报(“你好”);}
再见(函数)= 函数(){ 警报(“再见”);}
The next part of my challenge is to build something which can reflect back (if possible) an objects name, and the path to the object.
我挑战的下一部分是构建一些可以反映(如果可能)对象名称和对象路径的东西。
using this example:...
使用这个例子:...
var x = new Foo.Bar.Test();
How can I reflect back "Test", from x? For example:
我怎样才能从 x 反射回“测试”?例如:
ReflectName(x); //returns "Test";
Also how can I reflect back the path to x? For example:
另外我怎样才能反射回x的路径?例如:
ReflectPath(x) //returns Foo.Bar.Test
Is is possible to do these two things using JavaScript? I have researched this, and so far have not managed to come up with any viable solutions.
是否可以使用 JavaScript 来完成这两件事?我对此进行了研究,到目前为止还没有提出任何可行的解决方案。
I do not want a solution that requires hard coding the name and path of the object/function, as this would defeat the point of using reflection.
我不想要一个需要硬编码对象/函数的名称和路径的解决方案,因为这会破坏使用反射的意义。
回答by skalee
There are no classes in JavaScript (although due to code style which for reasons unknown to me imitates Java you could think there are some). Foo.Bar.Test
does not mean class Test
registered in namespace Foo.Bar
, but function which is assigned as attribute Test
of some object which is assigned as attribute Bar
of some object known as Foo
.
JavaScript 中没有类(尽管由于代码风格,我不知道为什么模仿 Java,你可能认为有一些)。 Foo.Bar.Test
并不意味着Test
在命名空间中注册的类Foo.Bar
,而是作为Test
某个对象的属性分配的函数,该函数被分配为Bar
某个称为Foo
.
You can't do reflection like "give me all variables to which number 7
is assigned", consequently you can't list all the objects which hold Test
in one of their attributes.
你不能像“给我7
分配了数字的所有变量”那样进行反射,因此你不能列出所有具有其中Test
一个属性的对象。
This is actually good and opens new possibilities,?but might be confusing in the beginning.
这实际上很好并开辟了新的可能性,但一开始可能会令人困惑。
BTW Since there are no classes in JavaScript, I believe term reflectionis not very fortunate. And new Foo()
does not mean "create new instance of Foo", but "create a new object and execute function Foo
in context of that object, and finally return it. Yeah, the new
keyword is very confusing, if you want to do anything more advanced in JavaScript, never trust your Java/C# experience. JavaScript fakes Java (I suppose to not scare newcomers and allow them to do easy things quickly), but it's very different.
BTW 由于 JavaScript 中没有类,我认为术语反射不是很幸运。并且new Foo()
并不意味着“创建 Foo 的新实例”,而是“创建一个新对象并Foo
在该对象的上下文中执行函数,最后返回它。是的,new
关键字很混乱,如果你想在 JavaScript 中做任何更高级的事情,永远不要相信你的 Java/C# 经验。JavaScript 伪造 Java(我想不是吓唬新人,让他们快速完成简单的事情),但它非常不同。
回答by thSoft
This is not possible in JavaScript. (To get a deeper understanding of JavaScript's type system, I recommend reading this.)
这在 JavaScript 中是不可能的。(为了更深入地了解 JavaScript 的类型系统,我建议阅读这篇。)
The best approximation you can do is querying over a staticJSON structure.
您可以做的最佳近似是查询静态JSON 结构。
回答by simon
Answer to your first question
回答你的第一个问题
function ReflectName(obj) { return obj.__proto__.constructor.name }
Second question is a bit more difficult and would require more setup with the definitions.
第二个问题有点困难,需要更多的定义设置。
It is answered a bit better here: Javascript objects: get parent
这里的回答要好一些:Javascript objects: get parent