JavaScript基础——常用数据类型分析

109 阅读8分钟

js从语言诞生之初到 ES6(ECMAScript 2015) 及其后的迭代更新,JavaScript 的数据类型体系持续进化、日益完善。熟练掌握这些核心要素,不仅能大幅提升开发者的编码效率,更能为实现复杂多样的功能需求筑牢根基。

一、基本数据类型

基本数据类型是 JavaScript 中最基础的数据存储单元,它们直接存储数据值,占据固定大小的内存空间。JavaScript 拥有种基本数据类型,分别是undefined、null、boolean、number、string、symbol和bigint。其中,symbolbigintES6 及后续版本新增的重要数据类型。

undefined

当一个变量被声明未被赋值时,它的值即为undefined。例如:

let variable;
console.log(variable); // 输出: undefined

此外,当访问对象中不存在的属性,或者函数没有明确的返回值时,同样会得到undefined。

null

null代表一个 “空” 值,常用于表示有意为空的对象指针,或者预期是对象但当前没有值的情况。如:

let emptyObject = null;

值得注意的是,使用typeof null会返回"object",这是 JavaScript 早期设计遗留的小问题。

boolean

boolean类型仅有true和false两个值,在逻辑判断中扮演着关键角色。例如:

let isCompleted = true;
let hasWarning = false;

在if、while等条件语句中,boolean值用于控制程序的执行流程。

number

number类型用于表示整数和浮点数,遵循 IEEE 754 标准,采用 64 位双精度浮点数存储数值。示例如下:

let intNum = 10;
let floatNum = 3.14;
let negativeNum = -5;

除十进制外,number类型还支持二进制(以0b或0B开头)、八进制(以0o或0O开头,仅在严格模式下有效)和十六进制(以0x或0X开头)的表示形式。此外,Infinity(无穷大)、-Infinity(负无穷大)和NaN(非数值)也是number类型的特殊值。

string

string类型用于存储文本数据,可由双引号(")、单引号(')或模板字面量(`)包裹。比如:

let message1 = "Hello, JavaScript!";
let message2 = '这是一段字符串。';
let name = "Alice";
let greeting = `欢迎,${name}!`; // 使用模板字面量进行字符串插值

string类型提供了众多实用方法,如length属性获取字符串长度,charAt()方法获取指定位置字符,split()方法分割字符串等。

symbol:ES6 新增的独特标识

symbol是 ES6 引入的新数据类型,它表示独一无二的值。即便使用相同的描述创建多个symbol,它们也互不相等。例如:

let symbol1 = Symbol("key");
let symbol2 = Symbol("key");
console.log(symbol1 === symbol2); // 输出: false

symbol常被用于创建对象的唯一属性名,避免属性名冲突,在大型项目和库开发中十分有用。比如:

const mySymbol = Symbol("uniqueProp");
const myObject = {
  [mySymbol]: "这是一个通过 symbol 定义的独特属性"
};

bigint:处理超大整数的利器

bigint是 ES2020 引入的新数据类型,用于表示大于Number.MAX_SAFE_INTEGER(即 2^53 - 1)的整数。在处理金额计算、密码学、区块链等需要精确表示大整数的场景中,bigint发挥着重要作用。创建bigint有两种方式:

  1. 在数字末尾添加n:
const largeNumber = 12345678901234567890n;
  1. 使用BigInt()构造函数:
const anotherLargeNumber = BigInt(98765432109876543210);

二、引用数据类型

引用数据类型与基本数据类型不同,它们不直接存储数据值,而是存储数据的引用(内存地址)。JavaScript 中,object是唯一的引用数据类型,它衍生出了Array(数组)、Function(函数)、Date(日期)、RegExp(正则表达式)等特殊对象。

object

普通对象是object类型的基础,以键值对形式存储数据,其中键只能字符串或者symbol类型。例如:


let person = {
    name: "Alice",  // "name" 是字符串类型的键
    age: 30,        // "age" 是字符串类型的键
    "city": "New York"  // 显式使用引号定义字符串键
};
console.log(person.name); // 使用点表示法访问 
console.log(person["age"]); // 使用方括号表示法访问
let key = "city"; 
console.log(person[key]); // 通过变量使用方括号表示法访问

// 使用symbol类型
const privateKey = Symbol("private"); 
let myObject = { 
    [privateKey]: "This is a private property" 
}; 
console.log(myObject[privateKey]); // 输出: This is a private property

可通过点表示法(user.name)或方括号表示法(user["age"])访问对象属性,还能动态添加、修改和删除属性。

Array

数组是特殊的对象,用于存储有序的数据集合,元素可以是任意数据类型。示例如下:

let colors = ["red", "green", "blue"];
let mixedArray = [1, true, "hello", {name: "Eve"}];

数组提供了丰富的方法,如push()添加元素、pop()删除元素、map()遍历映射、filter()筛选等。

Function

在 JavaScript 中,函数也是对象,可作为值传递、存储在变量中、作为参数传递给其他函数或作为函数的返回值,这赋予了 JavaScript 强大的函数式编程能力。例如:

function multiply(a, b) {
  return a * b;
}
let calculate = multiply;
console.log(calculate(4, 5)); // 输出: 20

函数支持默认参数、剩余参数和展开运算符等特性,增强了灵活性。

Date

Date对象用于处理日期和时间,可通过多种方式创建,如获取当前时间、指定特定日期时间。例如:

let currentTime = new Date();
let specificDate = new Date(2024, 0, 1); // 表示 2024 年 1 月 1 日

Date对象提供了一系列方法,用于获取和设置时间信息,进行时间比较和计算。

RegExp

RegExp对象用于处理正则表达式,是匹配和操作文本的强大工具。可使用字面量形式(/pattern/flags)或构造函数形式(new RegExp(pattern, flags))创建。例如:

let regex1 = /abc/;
let regex2 = new RegExp("abc");

正则表达式常用于表单验证、数据提取等场景。

三、数据类型检测

在 JavaScript 编程中,准确检测数据类型至关重要,能避免类型错误,确保程序正确运行。JavaScript 提供了typeof运算符、instanceof运算符和Object.prototype.toString.call()方法等多种检测方式。

typeof 运算符

typeof运算符是基础的数据类型检测方法,返回一个字符串表示操作数的数据类型。例如:

console.log(typeof 10); // 输出: "number"
console.log(typeof "world"); // 输出: "string"
console.log(typeof true); // 输出: "boolean"
console.log(typeof null); // 输出: "object"(存在历史问题)
console.log(typeof undefined); // 输出: "undefined"
console.log(typeof function() {}); // 输出: "function"

typeof对基本数据类型(除null)和函数检测较准确,但对nullobject类型区分存在局限。

instanceof 运算符

instanceof运算符用于检测一个对象是否是某个构造函数的实例,通过检查对象的原型链判断。例如:

let myArray = [];
console.log(myArray instanceof Array); // 输出: true
let myDate = new Date();
console.log(myDate instanceof Date); // 输出: true

instanceof适用于检测引用数据类型,对基本数据类型无效

Object.prototype.toString.call () 方法

Object.prototype.toString.call()方法是更准确、通用的数据类型检测方式,返回格式为[object Type]的字符串,Type表示实际数据类型。例如:

console.log(Object.prototype.toString.call(10)); // 输出: [object Number]
console.log(Object.prototype.toString.call("hello")); // 输出: [object String]
console.log(Object.prototype.toString.call(true)); // 输出: [object Boolean]
console.log(Object.prototype.toString.call(null)); // 输出: [object Null]
console.log(Object.prototype.toString.call(undefined)); // 输出: [object Undefined]
console.log(Object.prototype.toString.call([])); // 输出: [object Array]
console.log(Object.prototype.toString.call(function() {})); // 输出: [object Function]

该方法可准确区分各种数据类型,处理null和object类型的特殊情况。

四、检测数组

在 JavaScript 编程中,准确判断一个变量是否为数组是常见需求。除了上述通用的数据类型检测方法外,还有一些专门用于检测数组的方式。

Array.isArray () 方法

Array.isArray()是 ES5 引入的静态方法,用于判断一个值是否为数组,返回true或false,是最常用且准确的数组检测方式。例如:

let arr = [1, 2, 3];
let obj = {name: 'test'};
console.log(Array.isArray(arr)); // 输出: true
console.log(Array.isArray(obj)); // 输出: false

这种方式简单直接,兼容性良好,在大多数现代 JavaScript 环境中都能稳定使用。

instanceof 运算符检测数组

instanceof运算符通过检查对象的原型链,判断其是否为Array构造函数的实例,也可用于检测数组。例如:

let myArray = [4, 5, 6];
console.log(myArray instanceof Array); // 输出: true

不过,当存在多个全局执行环境(如在浏览器中多个框架创建的不同上下文)时,instanceof可能会出现误判,因为不同环境下的Array构造函数不是同一个引用。

Object.prototype.toString.call () 方法检测数组

使用Object.prototype.toString.call()方法,同样可以检测数组。该方法会返回[object Array]字符串来表明检测对象为数组,能精准识别数组,不受全局执行环境影响。例如:

let arr1 = [7, 8, 9];
console.log(Object.prototype.toString.call(arr1) === '[object Array]'); // 输出: true

这种方式通用性强,但代码相对冗长。

在实际开发中,开发者可根据具体场景选择合适的数组检测方法。如果仅需在单一执行环境下快速判断,Array.isArray()是最佳选择;若需要更通用、精准的检测,Object.prototype.toString.call()方法更为可靠;而instanceof在常规单一环境判断数组时也能胜任,但要注意多环境下的局限性。

总结

js的数据类型体系从基础到复杂,从传统到新增特性,构成了丰富多样的编程生态。无论是基础数据类型的灵活运用,还是引用数据类型的复杂操作,亦或是 ES6+ 新增数据类型带来的便利,都为开发者提供了强大的编程工具。深入理解这些数据类型,是熟练掌握 JavaScript 编程的必经之路。