JavaScript数据类型全解析,怎么区分呢?

打印 上一主题 下一主题

主题 892|帖子 892|积分 2676

在JavaScript里,数据类型就像是不同类型的“小盒子”,每个“小盒子”装的数据都有本身的特点,区分它们能帮助我们在编程时正确处理数据。下面用大白话给你讲讲常见的数据类型以及区分方法,还会配上代码示例。

  • 根本数据类型

    • 数字(number):就是我们平常说的各种数字,像整数1、2、3,小数3.14等都属于这个类型。在JavaScript里,它还能表现特别值,好比NaN(表现不是一个数字,像0除以0的结果),Infinity(无穷大,好比1除以0的结果) 。
    1. let num1 = 5;
    2. let num2 = 3.14;
    3. let num3 = NaN;
    4. let num4 = Infinity;
    5. console.log(typeof num1); // 输出 "number"
    6. console.log(typeof num2); // 输出 "number"
    7. console.log(typeof num3); // 输出 "number"
    8. console.log(typeof num4); // 输出 "number"
    复制代码
      

    • 字符串(string):就是用单引号''、双引号""或模板字符串``括起来的内容,好比'Hello'、"world"、`Hello, ${name}`(模板字符串可以嵌入变量) 。
    1. let str1 = '这是一个字符串';
    2. let str2 = "也可以用双引号";
    3. let name = '张三';
    4. let str3 = `你好,${name}`;
    5. console.log(typeof str1); // 输出 "string"
    6. console.log(typeof str2); // 输出 "string"
    7. console.log(typeof str3); // 输出 "string"
    复制代码
      

    • 布尔值(boolean):只有两个值,true(表现真)和false(表现假) ,常用来做判断。
    1. let bool1 = true;
    2. let bool2 = false;
    3. console.log(typeof bool1); // 输出 "boolean"
    4. console.log(typeof bool2); // 输出 "boolean"
    复制代码
      

    • 空值(null):表现一个“空”的对象指针,它只有一个值null,就好像一个空盒子,等着装对象,但如今还没装。
    1. let n = null;
    2. console.log(typeof n); // 输出 "object",这是JavaScript的一个历史遗留问题,实际上它是null类型
    复制代码
      

    • 未定义(undefined):当一个变量声明了但没有赋值时,它的值就是undefined,表现“未定义” 。
    1. let var1;
    2. console.log(var1); // 输出 undefined
    3. console.log(typeof var1); // 输出 "undefined"
    复制代码
      

    • 符号(symbol):是ES6新增的根本数据类型,每个symbol值都是唯一的,常用来创建对象的唯一属性。
    1. let sym1 = Symbol('描述');
    2. let sym2 = Symbol('描述');
    3. console.log(sym1 === sym2); // 输出 false
    4. console.log(typeof sym1); // 输出 "symbol"
    复制代码
      

    • 大整数(bigint):用来表现大于Number.MAX_SAFE_INTEGER(最大安全整数)的整数,在数字后面加n表现。
    1. let bigInt1 = 12345678901234567890n;
    2. console.log(typeof bigInt1); // 输出 "bigint"
    复制代码

  • 引用数据类型

    • 对象(object):可以理解为一个“大容器”,用来存放各种相干的数据和功能(方法) 。对象由键值对组成,键就像“小抽屉”的名字,值就是放在“小抽屉”里的东西。
    1. let person = {
    2.     name: '李四',
    3.     age: 20,
    4.     sayHello: function() {
    5.         console.log('你好,我是'+ this.name);
    6.     }
    7. };
    8. console.log(typeof person); // 输出 "object"
    9. person.sayHello(); // 输出 "你好,我是李四"
    复制代码
      

    • 函数(function):是一种特别的对象,它可以被调用执行一些操作。函数可以吸取参数,也可以返回值。
    1. function add(a, b) {
    2.     return a + b;
    3. }
    4. console.log(typeof add); // 输出 "function"
    5. let result = add(3, 5);
    6. console.log(result); // 输出 8
    复制代码

  • 区分数据类型的方法

    • typeof操作符:这是最常用的区分数据类型的方法,但它对null的判断有个“小坑” 。它会返回一个字符串,表明数据的类型。
    1. let num = 10;
    2. let str = 'test';
    3. let bool = true;
    4. let obj = { key: 'value' };
    5. let func = function() {};
    6. let nul = null;
    7. console.log(typeof num); // 输出 "number"
    8. console.log(typeof str); // 输出 "string"
    9. console.log(typeof bool); // 输出 "boolean"
    10. console.log(typeof obj); // 输出 "object"
    11. console.log(typeof func); // 输出 "function"
    12. console.log(typeof nul); // 输出 "object",实际是null类型
    复制代码
      

    • instanceof操作符:主要用来判断一个对象是否是某个构造函数的实例,也就是判断对象的类型。它不实用于根本数据类型(除了String、Number、Boolean这些包装对象) 。
    1. let arr = [1, 2, 3];
    2. console.log(arr instanceof Array); // 输出 true
    3. let date = new Date();
    4. console.log(date instanceof Date); // 输出 true
    复制代码
      

    • Object.prototype.toString.call()方法:这是一种更准确的判断数据类型的方法,它可以正确区分各种数据类型,包括null和undefined 。
    1. let num = 10;
    2. let str = 'test';
    3. let bool = true;
    4. let obj = { key: 'value' };
    5. let func = function() {};
    6. let nul = null;
    7. let und = undefined;
    8. console.log(Object.prototype.toString.call(num)); // 输出 "[object Number]"
    9. console.log(Object.prototype.toString.call(str)); // 输出 "[object String]"
    10. console.log(Object.prototype.toString.call(bool)); // 输出 "[object Boolean]"
    11. console.log(Object.prototype.toString.call(obj)); // 输出 "[object Object]"
    12. console.log(Object.prototype.toString.call(func)); // 输出 "[object Function]"
    13. console.log(Object.prototype.toString.call(nul)); // 输出 "[object Null]"
    14. console.log(Object.prototype.toString.call(und)); // 输出 "[object Undefined]"
    复制代码

除了根本数据类型,JavaScript尚有哪些数据类型?

1. 对象(Object)

对象是 JavaScript 中最常用的引用数据类型之一,可以把它想象成一个“容器”,用于存储各种数据和功能。它由键值对组成,键是字符串(ES6 开始也可以是 Symbol 类型),值可以是恣意数据类型,包括根本数据类型和其他引用数据类型。
代码示例
  1. // 创建一个对象
  2. const person = {
  3.     name: '张三',
  4.     age: 25,
  5.     hobbies: ['阅读', '跑步'],
  6.     sayHello: function() {
  7.         console.log(`你好,我是 ${this.name},今年 ${this.age} 岁。`);
  8.     }
  9. };
  10. // 访问对象的属性
  11. console.log(person.name); // 输出: 张三
  12. // 调用对象的方法
  13. person.sayHello(); // 输出: 你好,我是 张三,今年 25 岁。
复制代码
2. 数组(Array)

数组是一种特别的对象,用于存储有序的数据集合。数组中的每个元素都有一个对应的索引,索引从 0 开始。可以通过索引来访问、修改或删除数组中的元素。
代码示例
  1. // 创建一个数组
  2. const numbers = [1, 2, 3, 4, 5];
  3. // 访问数组元素
  4. console.log(numbers[2]); // 输出: 3
  5. // 修改数组元素
  6. numbers[3] = 10;
  7. console.log(numbers); // 输出: [1, 2, 3, 10, 5]
  8. // 数组的一些常用方法
  9. numbers.push(6); // 在数组末尾添加元素
  10. console.log(numbers); // 输出: [1, 2, 3, 10, 5, 6]
  11. const poppedElement = numbers.pop(); // 移除数组末尾的元素
  12. console.log(poppedElement); // 输出: 6
  13. console.log(numbers); // 输出: [1, 2, 3, 10, 5]
复制代码
3. 函数(Function)

函数也是一种引用数据类型,它可以被看作是一段可重复使用的代码块。函数可以吸取参数,执行特定的操作,并返回一个值。
代码示例
  1. // 定义一个函数
  2. function add(a, b) {
  3.     return a + b;
  4. }
  5. // 调用函数
  6. const result = add(3, 5);
  7. console.log(result); // 输出: 8
  8. // 函数可以作为参数传递给其他函数
  9. function multiplyByTwo(num) {
  10.     return num * 2;
  11. }
  12. function processNumber(num, callback) {
  13.     return callback(num);
  14. }
  15. const processedResult = processNumber(4, multiplyByTwo);
  16. console.log(processedResult); // 输出: 8
复制代码
4. 日期(Date)

Date 对象用于处理日期和时间。可以使用 new Date() 来创建一个表现当前日期和时间的对象,也可以传入特定的参数来创建指定日期和时间的对象。
代码示例
  1. // 创建一个表示当前日期和时间的对象
  2. const currentDate = new Date();
  3. console.log(currentDate); // 输出当前日期和时间
  4. // 创建一个指定日期的对象
  5. const specificDate = new Date('2024-10-01');
  6. console.log(specificDate); // 输出: 2024-10-01T00:00:00.000Z
  7. // 获取日期的各个部分
  8. const year = specificDate.getFullYear();
  9. const month = specificDate.getMonth() + 1; // 月份从 0 开始,所以要加 1
  10. const day = specificDate.getDate();
  11. console.log(`日期是 ${year} 年 ${month} 月 ${day} 日`); // 输出: 日期是 2024 年 10 月 1 日
复制代码
5. 正则表达式(RegExp)

正则表达式用于匹配和处理字符串。可以使用正则表达式来验证字符串的格式、查找特定的字符模式等。
代码示例
  1. // 创建一个正则表达式对象
  2. const pattern = /abc/;
  3. // 测试字符串是否匹配正则表达式
  4. const str1 = 'abcdef';
  5. const str2 = 'defabc';
  6. const str3 = 'defghi';
  7. console.log(pattern.test(str1)); // 输出: true
  8. console.log(pattern.test(str2)); // 输出: true
  9. console.log(pattern.test(str3)); // 输出: false
  10. // 使用正则表达式替换字符串中的内容
  11. const replacedStr = str1.replace(pattern, 'xyz');
  12. console.log(replacedStr); // 输出: xyzdef
复制代码
6. 集合(Set)和映射(Map)



  • Set:Set 对象是一种无序且唯一的数据集合。它类似于数组,但每个元素都是唯一的,不会有重复的值。
  • Map:Map 对象是一种键值对的集合,其中键和值可以是恣意数据类型,而且键是唯一的。
代码示例
  1. // 使用 Set
  2. const mySet = new Set([1, 2, 3, 2, 4]);
  3. console.log(mySet); // 输出: Set(4) { 1, 2, 3, 4 }
  4. // 检查元素是否存在
  5. console.log(mySet.has(3)); // 输出: true
  6. // 添加元素
  7. mySet.add(5);
  8. console.log(mySet); // 输出: Set(5) { 1, 2, 3, 4, 5 }
  9. // 使用 Map
  10. const myMap = new Map();
  11. myMap.set('name', '李四');
  12. myMap.set('age', 30);
  13. // 获取元素
  14. console.log(myMap.get('name')); // 输出: 李四
  15. // 检查键是否存在
  16. console.log(myMap.has('age')); // 输出: true
复制代码
这些引用数据类型在 JavaScript 中非常重要,它们各自具有不同的特点和用途,可以帮助我们更高效地处理和组织数据。
如何判断一个变量的数据类型
1. typeof 操作符



  • 原理:typeof 是一个一元操作符,它返回一个表现数据类型的字符串。可以快速判断根本数据类型,但对于一些引用数据类型的判断不敷细致。
  • 实用场景:实用于判断根本数据类型(如 number、string、boolean、undefined、symbol、bigint),以及区分函数和其他引用数据类型。
  • 代码示例
  1. let num = 10;
  2. let str = 'hello';
  3. let bool = true;
  4. let undef;
  5. let sym = Symbol('test');
  6. let big = 12345678901234567890n;
  7. let func = function() {};
  8. let obj = {};
  9. console.log(typeof num); // 输出: "number"
  10. console.log(typeof str); // 输出: "string"
  11. console.log(typeof bool); // 输出: "boolean"
  12. console.log(typeof undef); // 输出: "undefined"
  13. console.log(typeof sym); // 输出: "symbol"
  14. console.log(typeof big); // 输出: "bigint"
  15. console.log(typeof func); // 输出: "function"
  16. console.log(typeof obj); // 输出: "object"
复制代码


  • 范围性:typeof null 返回 "object",这是 JavaScript 的一个历史遗留问题;对于数组、日期等引用数据类型,typeof 都返回 "object",无法进一步区分具体类型。
2. instanceof 操作符



  • 原理:instanceof 用于判断一个对象是否是某个构造函数的实例。它会检查对象的原型链中是否存在该构造函数的 prototype 属性。
  • 实用场景:实用于判断对象是否为某个特定类的实例,常用于自定义类或内置对象(如 Array、Date 等)的判断。
  • 代码示例
  1. let arr = [1, 2, 3];
  2. let date = new Date();
  3. let obj = {};
  4. console.log(arr instanceof Array); // 输出: true
  5. console.log(date instanceof Date); // 输出: true
  6. console.log(obj instanceof Object); // 输出: true
复制代码


  • 范围性:instanceof 只能用于判断对象是否是某个构造函数的实例,对于根本数据类型无法使用;而且假如对象跨 iframe 传递,由于不同 iframe 有不同的全局对象,instanceof 判断可能会不准确。
3. Object.prototype.toString.call() 方法



  • 原理:调用 Object.prototype.toString 方法并通过 call 方法将其应用到要判断的变量上,该方法会返回一个包含具体数据类型信息的字符串。
  • 实用场景:可以准确判断各种数据类型,包括根本数据类型和引用数据类型。
  • 代码示例
  1. let num = 10;
  2. let str = 'hello';
  3. let bool = true;
  4. let undef;
  5. let nul = null;
  6. let arr = [1, 2, 3];
  7. let date = new Date();
  8. let func = function() {};
  9. console.log(Object.prototype.toString.call(num)); // 输出: "[object Number]"
  10. console.log(Object.prototype.toString.call(str)); // 输出: "[object String]"
  11. console.log(Object.prototype.toString.call(bool)); // 输出: "[object Boolean]"
  12. console.log(Object.prototype.toString.call(undef)); // 输出: "[object Undefined]"
  13. console.log(Object.prototype.toString.call(nul)); // 输出: "[object Null]"
  14. console.log(Object.prototype.toString.call(arr)); // 输出: "[object Array]"
  15. console.log(Object.prototype.toString.call(date)); // 输出: "[object Date]"
  16. console.log(Object.prototype.toString.call(func)); // 输出: "[object Function]"
复制代码


  • 缺点:返回的结果是一个字符串,需要进一步处理才气获取具体的类型名称;代码相对复杂一些。
4. Array.isArray() 方法



  • 原理:专门用于判断一个值是否为数组。
  • 实用场景:当需要明确判断一个变量是否为数组时使用。
  • 代码示例
  1. let arr = [1, 2, 3];
  2. let obj = {};
  3. console.log(Array.isArray(arr)); // 输出: true
  4. console.log(Array.isArray(obj)); // 输出: false
复制代码
5. Number.isNaN() 和 isNaN()



  • 原理

    • isNaN() 函数会先尝试将参数转换为数字,然后判断转换后的结果是否为 NaN。
    • Number.isNaN() 只判断参数本身是否严格即是 NaN。

  • 实用场景:用于判断一个值是否为 NaN。
  • 代码示例
  1. let nanValue = NaN;
  2. let strValue = 'abc';
  3. console.log(isNaN(nanValue)); // 输出: true
  4. console.log(isNaN(strValue)); // 输出: true,因为 'abc' 转换为数字是 NaN
  5. console.log(Number.isNaN(nanValue)); // 输出: true
  6. console.log(Number.isNaN(strValue)); // 输出: false,因为 'abc' 本身不是 NaN
复制代码
除了上述方法,尚有其他方式判断数据类型吗?

1. 使用 constructor 属性



  • 原理:在 JavaScript 中,每个对象都有一个 constructor 属性,它指向创建该对象的构造函数。通过检查这个属性,我们可以判断对象的数据类型。
  • 实用场景:对于自定义对象和一些内置对象的判断较为方便,但对于根本数据类型的包装对象和跨 iframe 情况可能存在问题。
  • 代码示例
  1. let num = 10;
  2. let str = 'hello';
  3. let arr = [1, 2, 3];
  4. let obj = {};
  5. console.log(num.constructor === Number); // 输出: true
  6. console.log(str.constructor === String); // 输出: true
  7. console.log(arr.constructor === Array); // 输出: true
  8. console.log(obj.constructor === Object); // 输出: true
复制代码


  • 范围性:constructor 属性可以被修改,一旦被修改,判断结果就会不准确;对于根本数据类型,直接使用 constructor 可能会有意外结果,因为根本数据类型本身没有 constructor 属性,只有它们的包装对象才有。别的,在跨 iframe 情况下,不同 iframe 的构造函数是不同的,会导致判断失误。
2. 自定义类型检查函数



  • 原理:结合前面提到的方法,封装一个更通用、更具针对性的类型检查函数,根据不同的需求举行类型判断。
  • 实用场景:当需要在项目中多次举行类型判断,且希望代码更轻便、更易于维护时使用。
  • 代码示例
  1. function getType(value) {
  2.     const type = typeof value;
  3.     if (type!== 'object') {
  4.         return type;
  5.     }
  6.     return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
  7. }
  8. let num = 10;
  9. let str = 'hello';
  10. let arr = [1, 2, 3];
  11. let date = new Date();
  12. let func = function() {};
  13. console.log(getType(num)); // 输出: "number"
  14. console.log(getType(str)); // 输出: "string"
  15. console.log(getType(arr)); // 输出: "array"
  16. console.log(getType(date)); // 输出: "date"
  17. console.log(getType(func)); // 输出: "function"
复制代码


  • 优点:可以根据具体需求灵活调整判断逻辑,代码复用性高,能提高开发效率。
3. 使用 Reflect 和 Symbol.toStringTag



  • 原理:Symbol.toStringTag 是一个内置的 Symbol 值,对象可以通过定义这个属性来自定义 Object.prototype.toString.call() 的返回值。而 Reflect 是一个内置对象,它提供了拦截 JavaScript 操作的方法。
  • 实用场景:对于一些需要自定义类型标识的对象,或者想要更深入地控制类型判断结果的情况。
  • 代码示例
  1. class MyCustomType {
  2.     get [Symbol.toStringTag]() {
  3.         return 'MyCustomType';
  4.     }
  5. }
  6. let myObj = new MyCustomType();
  7. console.log(Object.prototype.toString.call(myObj)); // 输出: "[object MyCustomType]"
复制代码


  • 作用:可以让对象拥有自定义的类型标识,方便在类型判断时举行区分。
4. 使用第三方库(如 Lodash)



  • 原理:Lodash 是一个非常流行的 JavaScript 实用工具库,它提供了许多用于数据类型判断的函数,这些函数经过了严格的测试和优化,具有较高的准确性和稳定性。
  • 实用场景:在大型项目中,当需要举行复杂的类型判断,或者希望减少本身编写类型判断代码的工作量时使用。
  • 代码示例
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
  6. </head>
  7. <body>
  8.     <script>
  9.         let arr = [1, 2, 3];
  10.         let date = new Date();
  11.         console.log(_.isArray(arr)); // 输出: true
  12.         console.log(_.isDate(date)); // 输出: true
  13.     </script>
  14. </body>
  15. </html>
复制代码


  • 优点:使用方便,函数功能强大且兼容性好,能减少开发者的工作量。但引入第三方库会增长项目的体积,需要根据实际情况权衡。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

圆咕噜咕噜

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表