【前端面试小册】JS-第1节,JavaScript数据类型详解与类型判断

1. JavaScript的10种数据类型

JavaScript中有10种数据类型,分为两大类:

1.1 基本数据类型(7种)

  • Number - 数字类型
  • String - 字符串类型
  • Boolean - 布尔类型
  • Undefined - 未定义类型
  • Null - 空值类型
  • Symbol - 符号类型(ES6新增)
  • BigInt - 大整数类型(ES2020新增)

1.2 引用数据类型(3种)

  • Object - 对象类型
  • Array - 数组类型(Object的子类型)
  • Function - 函数类型(Object的子类型)

面试重点:Array和Function本质上都是Object,但为了便于理解,通常单独列出。

2. 数据类型判断方法

2.1 最可靠的类型判断方法

const getType = (value) => {
    return Object.prototype.toString.call(value).match(/\s+(\w+)/)[1];
}

原理解析

  • Object.prototype.toString.call() 是获取对象内部[[Class]]属性的标准方法
  • 返回格式:[object TypeName]
  • 通过正则匹配提取类型名称

详细使用示例

// 测试各种数据类型的getType结果
console.log('=== 基本数据类型 ===');
console.log(getType(42));                    // "Number"
console.log(getType('hello'));               // "String"  
console.log(getType(true));                  // "Boolean"
console.log(getType(undefined));             // "Undefined"
console.log(getType(null));                  // "Null"
console.log(getType(Symbol('id')));          // "Symbol"
console.log(getType(123n));                  // "BigInt"

console.log('\n=== 引用数据类型 ===');
console.log(getType({}));                    // "Object"
console.log(getType([]));                    // "Array"
console.log(getType(function(){}));          // "Function"
console.log(getType(new Date()));            // "Date"
console.log(getType(/regex/));               // "RegExp"
console.log(getType(new Error()));           // "Error"
console.log(getType(new Map()));             // "Map"
console.log(getType(new Set()));             // "Set"
console.log(getType(new Promise(() => {}))); // "Promise"

console.log('\n=== 特殊对象类型 ===');
console.log(getType(document));              // "HTMLDocument" (浏览器环境)
console.log(getType(window));                // "Window" (浏览器环境)
console.log(getType(Math));                  // "Math"
console.log(getType(JSON));                  // "JSON"
console.log(getType(console));               // "Console"

console.log('\n=== 内部处理过程演示 ===');
const testValue = [1, 2, 3];
console.log('原始值:', testValue);
console.log('toString.call结果:', Object.prototype.toString.call(testValue));
console.log('正则匹配结果:', Object.prototype.toString.call(testValue).match(/\s+(\w+)/));
console.log('最终类型:', getType(testValue));

输出结果

=== 基本数据类型 ===
Number
String
Boolean
Undefined
Null
Symbol
BigInt

=== 引用数据类型 ===
Object
Array
Function
Date
RegExp
Error
Map
Set
Promise

=== 特殊对象类型 ===
HTMLDocument
Window
Math
JSON
Console

=== 内部处理过程演示 ===
原始值: [1, 2, 3]
toString.call结果: [object Array]
正则匹配结果: [" Array", "Array"]
最终类型: Array

与其他方法对比

// 对比不同方法的判断结果
const testValues = [
    null,
    undefined, 
    [],
    {},
    function(){},
    new Date(),
    /regex/,
    new Error(),
    new Map(),
    new Set()
];

console.log('值\t\t\tgetType\t\ttypeof\t\tinstanceof Array');
console.log('─'.repeat(80));

testValues.forEach(value => {
    const getTypeResult = getType(value);
    const typeofResult = typeof value;
    const isArrayResult = value instanceof Array;
    
    console.log(
        `${String(value).substring(0, 20).padEnd(20)}\t${getTypeResult.padEnd(10)}\t${typeofResult.padEnd(10)}\t${isArrayResult}`
    );
});

对比结果

测试值 getType typeof instanceof Array
null Null object false
undefined Undefined undefined false
[1,2,3] Array object true
{} Object object false
function(){} Function function false
new Date() Date object false
/regex/ RegExp object false
new Error() Error object false
new Map() Map object false
new Set() Set object false

关键优势

  • getType能准确区分Array、Object、Function等
  • typeof无法区分Array和Object,null显示为"object"
  • instanceof只能判断是否为特定构造函数的实例

2.2 类型判断工具函数

// 获取精确类型
const getType = (value) => {
    return Object.prototype.toString.call(value).match(/\s+(\w+)/)[1];
}

// 判断是否为指定类型
const isType = (target, type) => {
    return type.toLowerCase() === getType(target).toLowerCase();
}

// 常用类型判断函数
const isArray = (value) => isType(value, 'Array');
const isObject = (value) => isType(value, 'Object');
const isFunction = (value) => isType(value, 'Function');
const isString = (value) => isType(value, 'String');
const isNumber = (value) => isType(value, 'Number');
const isBoolean = (value) => isType(value, 'Boolean');
const isNull = (value) => isType(value, 'Null');
const isUndefined = (value) => isType(value, 'Undefined');
const isSymbol = (value) => isType(value, 'Symbol');
const isBigInt = (value) => isType(value, 'BigInt');

3. 完整示例演示

// 测试各种数据类型
const testValues = {
    function: function() {},
    object: {},
    array: [],
    undefined: undefined,
    null: null,
    boolean: false,
    string: 'hello',
    number: 42,
    symbol: Symbol('id'),
    bigint: BigInt(123)
};

// 测试类型判断
Object.entries(testValues).forEach(([key, value]) => {
    console.log(`${key}: ${getType(value)}`);
});

// 输出结果:
// function: Function
// object: Object  
// array: Array
// undefined: Undefined
// null: Null
// boolean: Boolean
// string: String
// number: Number
// symbol: Symbol
// bigint: BigInt

// 测试类型判断函数
console.log(isType(23, 'Number')); // true
console.log(isType('前端面试', 'String')); // true
console.log(isArray([1, 2, 3])); // true
console.log(isFunction(() => {})); // true

4. 为什么不能直接用toString()?

4.1 问题分析

// 直接使用toString()的问题
console.log("hello".toString());        // "hello"
console.log((123).toString());         // "123"
console.log([1,2,3].toString());       // "1,2,3"
console.log(new Date().toString());    // "Wed Dec 21 2016 20:35:48 GMT+0800"
console.log(function(){}.toString());  // "function(){}"
console.log(null.toString());          // TypeError: Cannot read property 'toString'
console.log(undefined.toString());     // TypeError: Cannot read property 'toString'

4.2 根本原因

  1. 重写问题:Array、Function等类型作为Object的实例,都重写了toString()方法
  2. null/undefined问题:这两个值没有toString()方法,会报错
  3. 目的不同toString()用于字符串转换,不是类型判断

4.3 解决方案对比

// ❌ 错误方式
const wrongType = (value) => {
    return value.toString(); // 会出错且不准确
}

// ✅ 正确方式  
const correctType = (value) => {
    return Object.prototype.toString.call(value).match(/\s+(\w+)/)[1];
}

5. 面试高频考点

5.1 typeof的局限性

console.log(typeof null);        // "object" (历史遗留问题)
console.log(typeof []);          // "object" (无法区分数组和对象)
console.log(typeof function(){}); // "function" (唯一能正确识别的引用类型)

5.2 instanceof的局限性

console.log([] instanceof Array);     // true
console.log([] instanceof Object);    // true (数组也是对象)
console.log(null instanceof Object);  // false (null不是对象)

5.3 最佳实践

// 综合判断方案
const typeChecker = {
    // 基本类型判断
    isString: (value) => typeof value === 'string',
    isNumber: (value) => typeof value === 'number' && !isNaN(value),
    isBoolean: (value) => typeof value === 'boolean',
    isUndefined: (value) => typeof value === 'undefined',
    isNull: (value) => value === null,
    isSymbol: (value) => typeof value === 'symbol',
    isBigInt: (value) => typeof value === 'bigint',
    
    // 引用类型判断
    isArray: (value) => Array.isArray(value),
    isFunction: (value) => typeof value === 'function',
    isObject: (value) => value !== null && typeof value === 'object' && !Array.isArray(value),
    
    // 通用判断
    getType: (value) => Object.prototype.toString.call(value).match(/\s+(\w+)/)[1]
};

6. 实际应用场景

6.1 参数验证

function processData(data) {
    const type = getType(data);
    
    switch(type) {
        case 'Array':
            return data.map(item => processData(item));
        case 'Object':
            return Object.keys(data).reduce((acc, key) => {
                acc[key] = processData(data[key]);
                return acc;
            }, {});
        case 'String':
            return data.trim().toLowerCase();
        case 'Number':
            return Math.round(data);
        default:
            return data;
    }
}

6.2 深拷贝实现

function deepClone(obj) {
    const type = getType(obj);
    
    if (type === 'Array') {
        return obj.map(item => deepClone(item));
    }
    
    if (type === 'Object') {
        const cloned = {};
        Object.keys(obj).forEach(key => {
            cloned[key] = deepClone(obj[key]);
        });
        return cloned;
    }
    
    return obj;
}

7. 总结

  • 核心方法Object.prototype.toString.call() 是最可靠的类型判断方法
  • 避免陷阱:不要使用typeof判断null和数组类型
  • 最佳实践:结合多种方法进行类型判断,根据具体场景选择合适的方法
  • 面试重点:理解为什么toString()不能用于类型判断,掌握各种类型判断方法的优缺点
#前端面试#
全部评论

相关推荐

从小父母离异家里没人管,靠着心里的不安和学校的环境也算是坚持到了学有所成的地步。到了大学环境开始松散不知道该做什么,只觉得在不挂科的基础上能往上考多少就考多少,等到秋招来临才发现自己有多么幼稚无能,今年九月份初才发现自己原来连一个求职的方向都没有。因为之前做过前后端一体的课设,算是有过了解,而对于其他岗位连做什么都不知道,因此这一个半个月在越来越焦虑的同时埋头苦学,事到如今想要活下去我似乎只能走前端这条路了,9月初先是靠着虚假夸大能力的简历得到一些笔试来确定了考察的方向,有一个大厂的无笔试面试最终是拒绝了没有勇气去面对。然后在这个基础上埋头苦学,如今也算是搭好了自己前端学习的框架和思考的瞄,可以逐渐给自己扩展新的知识和能力了,但这并不是一件多好的事儿,因为我发现学的越多越焦虑,学的越多便越无力。因为我感觉我如今努力学习的知识都是竞争对手们早就掌握了的东西,我如今困惑追求答案的难题早就被别人解决。别人早就能得心应手地做出项目而我连思考都会卡壳,看着别人的笔试和面经上那些闻所未闻的题目,我才知道别人到底有多强而我有多幼稚,我什么时候才能达到别人那种堪称熟练的能力呢?而且网上的焦虑越多越多,即便是真有这么高的能力最后也大概落得一个低薪打工人的下场,我真的感到迷茫。秋招都快结束了,而我还在继续痛苦的学习之旅,这些天找前端面试发现似乎问的有些简单跟网上搜到的内容不符(可能因为并不是大厂),我是不是本来就没打算被招所以别人懒得细问呢?我不知道,我只能继续总结下去学习下去,不管如何我都要活下去,如果我能早一些准备就好了,如果暑假能意识到现在这个情况就好了,可惜没有如果。种下一棵树的最好时间是十年前,其次是现在,虽然我相信自己的学习能力,但已经错过了最好的时机,只能在焦虑与痛苦中每天坚持学下去。目前的路还有很长很长,先去把typescript看了,再去巩固vue3的基础,再去练习elementui的使用,如果这能找到实习的话就好了。接下来呢?去学uniapp和小程序,不管如何我都要对得起曾经努力的自己。即便我们都感到痛苦,但我心中还是希望我们都能靠自己的努力来获取自己想要的幸福。
Chris552:走下去。停一停,歇一歇也好,但一定不要后退,不管是劝自己骗自己也好,一定要坚持走下去,走下去才有希望
一句话证明你在找工作
点赞 评论 收藏
分享
昨天 13:13
已编辑
早稲田大学 C++
鼠鼠秋招大大小小拿了十几个offer,其中年包最高50w+,在这里分享一下自己选offer的心得,仅供参考。1. 平台作为校招生,我认为第一个关注的就是平台。好的平台能带给你更高的见识、有机会接触到更前沿的东西,现实一点的话会给你后面的跳槽提供助力。想象一下你的社招简历,BAT/ATMD的工作经历和某不知名初创的工作经历,哪个更可能让人眼前一亮。另外,大公司的流程相对更正规,内部转岗机会也相对更多,裁应届卡转正的可能性也相对更小(大公司要面子,虽然个别公司不要脸,我们可以提前打听一下看看有没有前科)。2. 业务同一个公司的不同业务线,增长速度可以说是天差地别,一般来说c端业务>b端业务>对内业务(当然这并不绝对,具体情况具体分析,也要结合个人想要的是什么)。好的业务能得到的锻炼更多,晋升更快,绩效更好,跳槽认可度也更高。想象一下,做三年交易/支付链路,和做三年内部系统,哪个更有增长点。3. 薪资说到底打工是为了赚钱,在平台和业务差不多的情况下,💰就很重要了。其中月base高>薪数多,因为跳槽是看月base的,一般卡30%涨幅,你现在的base越高,跳槽涨的就越多。公积金也是按base算的,你的base越高,公司给你交的那部分公积金就越多。说到公积金,这块也是要重点关注的,假设base是20k,5%的公积金一年要比12%的公积金少差不多17k,相当于一个月工资了。另外,很多公司的总包可能会含股票或者期权,甚至还可能含绩效,这里给一个暴论,除非有绝对看涨的趋势,否则都不如纯现金,这点可以在选offer的时候做参考。4. 行业那句话怎么说来着,站在风口上,猪都能飞起来。这里说的就是行业了,试想你在二十年前入行互联网,十五年前入行房地产,十年前入行手游,现在是不是赚的盆满钵满了。所以选行业也是非常重要的,朝阳行业肯定优于夕阳行业(前提是这个朝阳在日出前不要暴毙),怎么选行业是个技术活,但毕竟谁也无法预知未来,我的建议是尽量选前沿并且感兴趣的行业,这样既有可能吃到红利,又不至于后面后悔。差不多就是这些,其他像组内氛围/工作城市等等因素变数太多,因人而异,需要综合考虑,祝大家都能收获自己理想的offer。
从哪些方向判断这个off...
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务