JavaScript 数据类型详解
在前端开发中,JavaScript 是一种不可或缺的语言。理解 JavaScript 的数据类型及其内存分配机制,对于编写高效、可靠的代码至关重要。本文将详细介绍 JavaScript 中的数据类型,包括简单数据类型和复杂数据类型,并探讨它们的内存分配机制、拷贝方式以及如何准确判断变量的类型。
JavaScript 数据类型概述
JavaScript 是一种动态类型语言,提供了多种数据类型来满足不同的编程需求。根据 ES6 的引入,JavaScript 数据类型可以分为七种或八种,具体如下:
这里的
Number类型和Bigint类型可以归为Numeric一种类型。
内存分配机制
在 JavaScript 中,简单数据类型和复杂数据类型的内存分配机制是不同的。
- 简单数据类型:存储在栈内存中,直接存储实际的值。
- 复杂数据类型:存储在堆内存中,栈内存中存储的是指向堆内存的地址。
拷贝方式
- 简单数据类型:按值拷贝,即复制实际的值。
// 值拷贝
let a = 1;
let b = a;
b = 3;
console.log(a,b); // 1, 3
- 复杂数据类型:按引用拷贝,即复制指向堆内存的地址。
// 对象字面量
let obj = {
name:'obj',
job:'前端开发工程师',
company:'腾讯'
}
let obj2 = obj;
obj2.name = '染染';
console.log(obj,obj2);
简单数据类型(Primitive Types)
1. number
-
表示数值,包括整数和浮点数。
-
示例:
let num = 123; let floatNum = 3.14;
2.ES6新增类型 bigint
JS是一门具有强大的表现力的语言,适合前端, 但是 不擅长计算,容易精度丢失。
示例:
//数子范围有限
let num1 = 999999999999999999999999999;
let num12 =123455474424316547664653536;
console.log(num1+num12); //计算结果不精确
-
所以ES6推出了
Bigint类型-
表示大整数,用于处理超过
Number.MAX_SAFE_INTEGER的整数。 -
示例:
let bigNum = 999999999999999999999999999n; let anotherBigNum = 123455474424316547664653536n; console.log(bigNum + anotherBigNum); // 计算结果 -
3. string
-
表示文本字符串。
-
示例:
let str = "Hello, World!";
4. boolean
-
表示布尔值,只有
true和false两种值。 -
示例:
let isTrue = true; let isFalse = false;
5. null
-
表示一个空值或不存在的对象。
-
示例:
let a = null; // 栈内存 console.log(a); // 堆内存 对象 let largeObject = { data:new Array(10000000000).fill('a'), } // 设计为null类型 释放内存 largeObject = null; console.log(largeObject); -
用途:通常用于表示某个值尚未被赋值或已经释放的空间。
-
内存回收:显式回收内存。
6. undefined
-
表示一个未定义的值,通常用于声明但未赋值的变量。
-
示例:
let undeclared; console.log(undeclared); // 输出 undefined
7. symbol
-
表示唯一的值,常用于对象属性的键。
-
示例:
let sym1 = Symbol('马斯克'); let sym2 = Symbol('马斯克'); console.log(sym1 === sym2); // 输出 false
复杂数据类型(Complex Types)
1. object
-
表示复杂的数据结构,可以包含多个属性和方法。
-
示例:
let person = { name: "Alice", age: 25, greet: function() { console.log("Hello, " + this.name); } }; person.greet(); // 输出 "Hello, Alice"
特殊的复杂数据类型
函数
-
函数在 JavaScript 中是一种
特殊的对象,称为函数对象。 -
函数可以有属性和方法,可以作为参数传递,也可以作为返回值返回。
-
示例:
function greet(name) { console.log("Hello, " + name); } let greetingFunction = greet; greetingFunction("Bob"); // 输出 "Hello, Bob"
数组
-
数组是一种特殊的对象,用于存储多个值。
-
数组是可遍历和迭代的。
-
示例:
let numbers = [1, 2, 3, 4, 5]; for (let num of numbers) { console.log(num); } -
for...of循环是 ES6 引入的一种新的循环结构,用于遍历可迭代对象(如数组、字符串、Map、Set 等)。 -
let num of numbers:这行代码表示每次循环时,将numbers数组中的一个元素赋值给变量num。
类型判断
typeof 操作符
-
typeof操作符可以用来判断变量的类型,但对于null类型会返回"object",这是 JavaScript 设计时的一个 bug。 -
示例:
console.log(typeof 123); // "number" console.log(typeof "hello"); // "string" console.log(typeof true); // "boolean" console.log(typeof null); // "object" (错误) console.log(typeof undefined); // "undefined" console.log(typeof Symbol('test')); // "symbol" console.log(typeof {}); // "object" console.log(typeof []); // "object" console.log(typeof function() {}); // "function"
instanceof 操作符
-
instanceof操作符可以用来判断一个对象是否是某个构造函数的实例。 -
示例:
let arr = []; console.log(arr instanceof Array); // true console.log(arr instanceof Object); // true
Object.prototype.toString.call 方法
-
使用
Object.prototype.toString.call方法可以准确判断变量的类型。 -
示例:
console.log(Object.prototype.toString.call(123)); // "[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(Symbol('test'))); // "[object Symbol]"
console.log(Object.prototype.toString.call({})); // "[object Object]"
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call(function() {})); // "[object Function]"
总结
JavaScript 提供了丰富的数据类型,包括简单数据类型和复杂数据类型。了解这些数据类型的内存分配机制、拷贝方式以及如何准确判断变量的类型,对于编写高效、可靠的 JavaScript 代码至关重要。希望本文能帮助你更好地理解和使用 JavaScript 的数据类型。如果有更多问题或需要进一步的示例,请随时提问。
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏和分享!也欢迎关注我的其他技术文章,了解更多前端开发的知识和技巧。