0

由于对检测数据类型的需求不断出现,我写了以下函数,到目前为止效果很好,所以我想把代码分享给你。但是我开始认为这可能不是类型检测的有效方法。我怎样才能增强这个功能?还是我犯了一个错误,甚至不应该这样做?

根据 cade 的回答,我查看并编辑了代码:

function detectType(data) {
    // analyze data to distinguish object types from primitive types
    var dataType = typeof data;
    var toClass = {}.toString; // this is used to detect object types
    var isPrimitive;
    var isFalsy = false;
    switch(dataType) {
        case 'string':
            isFalsy = !data;
            if(isFalsy) {
                dataType = 'empty string'; // Only if you want to distingush empty strings
            }
            isPrimitive = true;
            break;
        case 'number':
            isFalsy = !data;
            if(isFalsy) {
                if(isNaN(data))
                    dataType = 'NaN';   // it is strange that JavaScript considers NaN a number
                else {
                    dataType = '0';     // only needed if you want to distinguish zeros
                    if(1/data < 1/0)
                        dataType = '-0';
                }
            } else if(!isFinite(data)) {    // Although infinity is considered a number you might want to distinguish it
                dataType = 'infinity';
                if(data < Infinity)
                    dataType = '-infinity';
            }
            isPrimitive = true;
            break;
        case 'boolean':
            isFalsy = !data;
            isPrimitive = true;
            break;
        case 'object':
            isFalsy = !data;
            dataType = toClass.call(data).slice(8, -1).toLowerCase();
            switch(dataType) {
                case 'string':
                    dataType = 'object string';
                    break;
                case 'number':
                    dataType = 'object number';
                    break;
                case 'boolean':
                    dataType = 'object boolean';
                    break;
            }
            isPrimitive = false;
            break;
        case 'function':
            isFalsy = !data;
            isPrimitive = false;
            break;
        case 'undefined':
            isFalsy = !data;
            isPrimitive = false;
            break;
        }
    return [dataType, isPrimitive ,isFalsy];
}

我在控制台中尝试了一些东西并得到了这些结果:

detectType(-0)
["-0", true, true]
detectType(9)
["number", true, false]
detectType(new Number(3))
["object number", false, false]
detectType('')
["empty string", true, true]
detectType('foo')
["string", true, false]
detectType(new String('bar'))
["object string", false, false]
detectType(true)
["boolean", true, false]
detectType(new Boolean(false))
["object boolean", false, false]
detectType(document.body)
["htmlbodyelement", false, false]
detectType(-0)
["-0", true, true]
detectType(-Infinity)
["-infinity", true, false]
detectType(/a-zA-Z/)
["regexp", false, false]

现在它甚至可以检测 html 元素,可以检查 -0、+0 和 -Infinity、+Infinity,虽然这些被认为是数字,但人们可能会发现区分太大或太小的数字很有用,例如无穷大或-0。

4

2 回答 2

1

您的大部分 switch/case 控制语句都可以被删除和替换为:

  toClass.call(obj).slice(8, -1);

获取类型。这将去除多余的绒毛并返回

Number, Function, etc, ...

此外,typeof不适用于 null 和数组,因为它们被报告为对象。

您的虚假逻辑可以简化为:

!data

我喜欢你如何使用typeoftoString区分

3

new Number(3)

即使第二种形式不是最佳实践。

于 2013-07-09T22:59:00.450 回答
1

如果您想改进您当前使用的功能的功能,我会查看underscore.js 注释代码。Underscore 是一个用于 javascript 的实用程序库,包含许多有用的功能。它们至少有 15 个不同的 'is[Type]' 函数(例如 isString、isArray)。

如果您向下滚动带注释的代码并查看这些函数,我相信您将能够找到一些有用的注释。

如果您决定不继续处理此问题,则下划线是增强 typeof 的绝佳选择。

祝你好运。

于 2013-07-09T23:01:40.243 回答