请叫我阿布 發表於 2026-1-12 08:19:53

JavaScript准确判断数据类型的5 种方法深度对比

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">1. typeof 操作符</a></li><li><a href="#_label1">2. instanceof 操作符</a></li><li><a href="#_label2">3. Object.prototype .toString.call()</a></li><li><a href="#_label3">4. 专用方法</a></li><ul class="second_class_ul"><li><a href="#_lab2_3_0">判断数组:Array.isArray()</a></li><li><a href="#_lab2_3_1">判断NaN:Number.isNaN()</a></li><li><a href="#_lab2_3_2">判断有限数字:Number.isFinite()</a></li></ul><li><a href="#_label4">编写健壮的函数</a></li><ul class="second_class_ul"><li><a href="#_lab2_4_3">场景1:安全的数字相加</a></li><li><a href="#_lab2_4_4">场景2:处理多种数据类型</a></li></ul><li><a href="#_label5">总结:选择合适的方法</a></li><ul class="second_class_ul"></ul></ul></div><p>在写js的时候,很容易因为数据类型没判断好而出错,比如这样的代码:</p>
<div class="jb51code"><pre class="brush:js;">function calculate(a, b) {
    return a + b;
}
// 我以为是 10 + 20 = 30
calculate(10, 20); // 结果 30 对的

// 实际上用户输入的是字符串和数字
calculate("10", 20); // 结果为 "1020"
</pre></div>
<p>所以为了避免这种情况的出现,我们还是要去判断好数据类型。</p>
<p>在<code>JavaScript</code>中,有几种方式来判断数据类型,以下是常用的方法:</p>
<p class="maodian"><a name="_label0"></a></p><h2>1. typeof 操作符</h2>
<p>最常用的类型判断方法,但有一些局限性:</p>
<div class="jb51code"><pre class="brush:js;">typeof 42;         // "number"
typeof "hello";      // "string"
typeof true;         // "boolean"
typeof undefined;    // "undefined"
typeof null;         // "object" (历史遗留问题)
typeof {};         // "object"
typeof [];         // "object"
typeof function(){}; // "function"
typeof Symbol();   // "symbol"
typeof 42n;          // "bigint"
</pre></div>
<p><strong>局限性</strong>:</p>
<ul><li>无法区分数组、对象和 <code>null</code></li><li>函数返回 <code>function</code></li><li><code>typeof</code> 适合判断基本类型,但遇到对象类型就力不从心了</li></ul>
<p class="maodian"><a name="_label1"></a></p><h2>2. instanceof 操作符</h2>
<p>用于检测构造函数的 <code>prototype</code> 属性是否出现在对象的原型链中:</p>
<div class="jb51code"><pre class="brush:js;">[] instanceof Array;         // true
{} instanceof Object;          // true
new Date() instanceof Date;    // true
function(){} instanceof Function; // true

// 继承关系,数组也是对象
[] instanceof Object;          // true
</pre></div>
<p><code>instanceof</code> 的局限性:</p>
<div class="jb51code"><pre class="brush:js;">// 基本类型用不了
42 instanceof Number;          // false
"hello" instanceof String;   // false
</pre></div>
<p>在跨 <code>iframe</code> 或不同 <code>window</code> 环境下可能失效(因为构造函数不同)</p>
<p class="maodian"><a name="_label2"></a></p><h2>3. Object.prototype .toString.call()</h2>
<p>这是最准确、最可靠的方法,能识别所有内置类型!</p>
<div class="jb51code"><pre class="brush:js;">Object.prototype.toString.call(42);         // ""
Object.prototype.toString.call("hello");      // ""
Object.prototype.toString.call(true);         // ""
Object.prototype.toString.call(null);         // ""
Object.prototype.toString.call(undefined);    // ""
Object.prototype.toString.call([]);         // ""
Object.prototype.toString.call({});         // ""
Object.prototype.toString.call(function(){}); // ""
Object.prototype.toString.call(Symbol());   // ""
Object.prototype.toString.call(42n);          // ""
</pre></div>
<p>我们封装一个实用的工具函数:</p>
<div class="jb51code"><pre class="brush:js;">function getRealType(value) {
    return Object.prototype.toString.call(value)
      .slice(8, -1)          // 截取""之间的内容
      .toLowerCase();         // 转为小写,更友好
}

console.log(getRealType([]));      // "array"
console.log(getRealType(null));      // "null"
console.log(getRealType({}));      // "object"
console.log(getRealType(new Date())); // "date"
</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>4. 专用方法</h2>
<p>对于一些特殊类型,JavaScript提供了专门的判断方法:</p>
<p class="maodian"><a name="_lab2_3_0"></a></p><h3>判断数组:Array.isArray()</h3>
<div class="jb51code"><pre class="brush:js;">Array.isArray([]);   // true
Array.isArray({});   // false
Array.isArray("123");// false
</pre></div>
<p class="maodian"><a name="_lab2_3_1"></a></p><h3>判断NaN:Number.isNaN()</h3>
<div class="jb51code"><pre class="brush:js;">// 注意区别!
isNaN("hello");      // true← 字符串不是数字,但这样判断容易误解
Number.isNaN("hello"); // false ← 更准确:只有真正的NaN才返回true
Number.isNaN(NaN);   // true
</pre></div>
<p class="maodian"><a name="_lab2_3_2"></a></p><h3>判断有限数字:Number.isFinite()</h3>
<div class="jb51code"><pre class="brush:js;">Number.isFinite(42);   // true
Number.isFinite(Infinity); // false← 无穷大不是有限数字
Number.isFinite("42");   // false← 字符串不是数字
</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>编写健壮的函数</h2>
<p>在实际开发中的应用:</p>
<p class="maodian"><a name="_lab2_4_3"></a></p><h3>场景1:安全的数字相加</h3>
<div class="jb51code"><pre class="brush:js;">function safeAdd(a, b) {
    // 确保两个参数都是数字类型
    if (typeof a !== 'number' || typeof b !== 'number') {
      throw new Error('参数必须是数字');
    }
    return a + b;
}

safeAdd(1, 2);   // 3
safeAdd(1, "2");   // 报错:参数必须是数字
</pre></div>
<p class="maodian"><a name="_lab2_4_4"></a></p><h3>场景2:处理多种数据类型</h3>
<div class="jb51code"><pre class="brush:js;">function processData(data) {
    // getRealType方法在第3点Object.prototype.toString.call()中有写
    const type = getRealType(data);
   
    switch(type) {
      case 'array':
            return data.map(item =&gt; item * 2);
      case 'object':
            return Object.keys(data).length;
      case 'string':
            return data.toUpperCase();
      case 'number':
            return data * 2;
      default:
            return '不支持的数据类型';
    }
}

console.log(processData());    //
console.log(processData("hello"));      // "HELLO"
console.log(processData({a: 1, b: 2})); // 2
</pre></div>
<p class="maodian"><a name="_label5"></a></p><h2>总结:选择合适的方法</h2>
<table><thead><tr><th>场景</th><th>推荐方法</th><th>示例</th></tr></thead><tbody><tr><td>判断基本类型</td><td>typeof</td><td>typeof &quot;hello&quot; === &quot;string&quot;</td></tr><tr><td>判断数组</td><td>Array.isArray()</td><td>Array.isArray([])</td></tr><tr><td>判断自定义对象</td><td>instanceof</td><td>obj instanceof MyClass</td></tr><tr><td>精确类型判断</td><td>Object.prototype.toString.call()</td><td>见上文工具函数</td></tr><tr><td>特殊值判断</td><td>专用方法</td><td>Number.isNaN(), Number.isFinite()</td></tr></tbody></table>
頁: [1]
查看完整版本: JavaScript准确判断数据类型的5 种方法深度对比