更新这里是最终的和正在运行的代码 - 以防有人发现它有用:jsfiddle
我把它写成了类型检测器。它在所有情况下都能很好地工作 - 到目前为止,无论我测试过什么,但只在一种情况下失败。
首先,这是片段:jsfiddle
var TypeOf = function ( thing ) {
var typeOfThing = typeof thing;
if ( typeOfThing === 'object' ) {
typeOfThing = Object.prototype.toString.call(thing);
if ( typeOfThing === '[object Object]') {
if ( thing.constructor.name )
typeOfThing = thing.constructor.name;
else if ( thing.constructor.toString().charAt(0) === '[' )
typeOfThing = typeOfThing.substring(8,typeOfThing.length - 1);
else
typeOfThing = thing.constructor.toString().match(/function\s*(\w+)/)[1];
} else {
typeOfThing = typeOfThing.substring(8,typeOfThing.length - 1);
}
return typeOfThing.toLowerCase();
} else {
return typeOfThing;
}
}
问题在于,如果我在parse-time
定义函数,那么它将完全正常工作:
function me () {};
var you = new me();
console.log('Type of you: ' + TypeOf(you)); // me
但是,如果我只是在run-time
定义它,那么它将不起作用:
var me = function () {};
var you = new me();
console.log('Type of you: ' + TypeOf(you)); // nope
据我在解析时的情况看,constructor
类似于function me () {}
,所以我可以使用/function\s*(\w+)/
来获取它,但是在运行时情况下构造函数是function () {}
。
有什么方法可以让它发挥作用吗?此外,还有其他任何情况下此代码段可能无法检测到类型吗?
更新作为评论中提到的@lonesomeday,似乎我正在尝试获取匿名函数的名称。这对我来说有点吓人。这甚至可能吗?
更新,如下所述@jackson,似乎正确的输出应为function
而不是me
。这是真的正确吗?
答案 0 :(得分:2)
你的测试确实成功了。该变量的类型确实是“函数”。
考虑到你的function me () {};
在你的测试中的并置,你似乎已经预料到附近的语法略有修改的测试会产生类似的结果。但这种情况并非如此。 you
没有理由拥有“我”的“阶级”(实际上不是一个阶级)。它只是一个常规的旧“功能”,仅此而已。
答案 1 :(得分:1)
该变量的构造函数的类型是function
,而不是me
。您的第二个示例使用的是一个恰好由名为me
的变量引用的匿名函数。
考虑如果将me
重新分配给其他对象会发生什么:
var me = function () {};
var you = new me();
me = 10;
//what if TypeOf(you) had returned me? that would be confusing, because me is now an integer
如果您关心存储匿名函数的变量的名称(由于上述原因,这是一件很脆弱的事情),您可以使用此解决方法。
它找到 global 变量的名称,当前包含对象构造函数的引用:
function checkForAnAnonymousConstructor(o) {
for(var f in window) {
if(window[f] == o.constructor) return f;
}
}
me = function() { }
var you = new me();
console.log(checkForAnAnonymousConstructor(you)); //-> me
//This only works whilst the reference is current
me = 10
console.log(checkForAnAnonymousConstructor(you));// -> undefined
答案 2 :(得分:0)
你必须考虑有关JavaScript函数的一个非常重要的观点,这是你定义它们的方式。当你执行var me = function () {}
时,你实际上创建了一个匿名函数,一个没有任何名字的函数,然后将它分配给一个变量。
当你创建这样的函数时:
function myfunc(){}
实际上就像:
var myfunc = function myfunc(){};
这里最重要的一点是,函数的名称不是唯一的,你可以用同一个名字创建几个函数。
var Func1 = function myfuncname(){ this.name = 'Func1'; };
或
var Func2 = function myfuncname(){ this.name = 'Func2'; };
如您所见,我们有两个不同的功能,如果您使用TypeOf
功能,结果是相同的:
TypeOf(new Func1) -> myfuncname
以及
TypeOf(new Func2) -> myfuncname
顺便说一下,你的TypeOf
功能是完全正确的,但这里唯一的问题是,如果你想得到正确的结果,你必须改变:
var me = function () {};
var you = new me();
console.log('Type of you: ' + TypeOf(you));
为:
var me = function me() {};
var you = new me();
console.log('Type of you: ' + TypeOf(you));
我之前已经完成了这项艰巨的任务,我很乐意分享你需要的任何东西。