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, ...

また、typeofnull と配列はオブジェクトとして報告されるため、機能しません。

偽りのロジックは次のように単純化できます。

!data

私はあなたがどのように使用typeoftoString、区別するのが好きです

3

new Number(3)

2 番目の形式はベスト プラクティスではありませんが。

于 2013-07-09T22:59:00.450 に答える
1

現在使用している関数の機能を改善したい場合は、underscore.js 注釈付きコードをチェックしてください。Underscore は JavaScript 用のユーティリティ ライブラリであり、多くの便利な機能が含まれています。これらには、少なくとも 15 の異なる「is[Type]」関数があります (例: isString、isArray)。

注釈付きのコードを下にスクロールしてそれらの機能を確認すると、役立つコメントがいくつか見つかるはずです。

これに取り組まないことに決めた場合、アンダースコアはタイプの拡張に最適なオプションです。

幸運を。

于 2013-07-09T23:01:40.243 に答える