获取对象类型

Get the object type

本文关键字:类型 取对象 获取      更新时间:2024-04-11

更新这里是最终的工作代码,以防有人发现它有帮助: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 () {}

有什么办法让它发挥作用吗?此外,在其他情况下,这个片段是否可能无法检测到类型?

更新正如@loneomeday在评论中提到的那样,我似乎正在尝试获取一个匿名函数的名称。这在我看来有点可怕。这可能吗?

更新正如@jackson下面所说,似乎正确的输出应该是function而不是me。这真的正确吗?

您的测试实际上成功了。该变量的类型实际上是"函数"。

考虑到function me () {};在测试中的并置,您似乎已经预料到附近稍微修改语法的测试会有类似的结果。但事实并非如此。you没有理由拥有"我"这样的"类"(实际上不是一个类)。这只是一个常规的老"函数",仅此而已。

该变量的构造函数的类型是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

如果您确实关心存储匿名函数的变量的名称(由于上述原因,这是一件很脆弱的事情),则可以使用此解决方法。

它找到全局变量的名称,当前持有对对象构造函数的引用:

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

http://jsfiddle.net/nE9eP/2

您必须考虑关于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));

我以前经历过这项艰巨的任务,我很乐意与您分享任何需要的东西。