一、JS是什么类型的语言
int main() {
int a = 1;
char b = "竹合";
bool c = true;
return 0;
}
这是一段c语言代码,在使用之前需要先去定义变量数据类型的语言称为静态语言。
let a = 1;
let b = "竹合";
let c = true;
这是一段JS代码,在使用之前不需要先定义变量数据类型,在运行时检查数据类型的语言称为动态语言。
在c语言中
c = a;
可以将int类型的变量a赋值给bool类型的变量c,因为在这个过程中发生了隐式类型转换,支持隐式类型转换的语言称为弱类型语言,不支持隐式类型转换的语言称为强类型语言。
显然JS是一种弱类型的、动态的语言。
弱类型: 意味不需要告诉JS引擎变量是什么类型的,JS引擎在运行代码时会自己计算出来。
动态: 意味着可以使用一个变量来保存不同类型的数据。
1. JS的数据类型
JavaScript有以下基本的数据类型:
- Number(数字): 用于表示整数或浮点数。例如:42、3.14
- String(字符串): 用于表示文本。例如:"Hello, World!"
- Boolean(布尔): 用于表示逻辑值,即 true、false
- Undefined(未定义): 表示声明了变量但未给它赋值时的默认值。
- Null(空): 表示空值或无值。typeof null"object"
- Object(对象): 引用数据类型 用于表示复杂数据结构,可以包含键值对。例如:{ key: 'value' }
- Symbol(符号): 用于创建唯一的标识符。引入于 ECMAScript 6。
- BigInt(大整数): BigInt 是 JavaScript 中引入的一种新的基本数据类型,用于表示任意精度的整数。在 ECMAScript 2020(ES11)中正式加入了 BigInt。
BigInt 类型的值可以表示比 Number 类型更大的整数,且不会丧失精度。它的字面量表示形式是在整数末尾加上 "n" 或者通过 BigInt() 构造函数创建。
// 使用 BigInt 字面量
const bigIntLiteral = 1234567890123456789012345678901234567890n;
// 使用 BigInt 构造函数
const bigIntConstructed = BigInt("1234567890123456789012345678901234567890");
console.log(bigIntLiteral);
console.log(bigIntConstructed);
JavaScript 还有一种特殊的数据类型:
Function(函数):函数在 JavaScript 中被视为一种特殊的对象,可以被调用。
此外,JavaScript 还有一些复合数据类型,如数组和日期对象。数组是一种特殊的对象,日期是一种特殊的对象类型。
// 示例
let num = 42; // Number
let str = "Hello"; // String
let bool = true; // Boolean
let und = undefined; // Undefined
let nul = null; // Null
let obj = { key: "value" }; // Object
let sym = Symbol("symbol"); // Symbol
// 特殊的对象类型
let arr = [1, 2, 3]; // Array
let func = function () {}; // Function
let date = new Date(); // Date
2.内存空间
3.栈空间和堆空间
function foo() {
var a = "竹合";
var b = a;
var c = { name: "竹合" };
var d = c;
}
foo();
接下来执行到第四行代码,JS引擎判断右边的值是一个引用数据类型,JS引擎的处理是将他分配到堆空间里面,然后将所在堆空间的地址存在栈空间中
如图可以知道,在JS引擎中,原始类型的数据值直接存储在栈空间中,引用类型数据的值存在堆空间中。
那么执行到第五行就是这样子
二、原始类型和引用类型
原始类型(原始值,Primitive Types):
- 存储在栈空间: 原始类型的数据值(比如数字、字符串、布尔值等)通常是固定大小的,它们的值直接存储在栈内存中。栈内存是一种有限且相对较小的内存区域,它的分配和释放速度较快。
- 快速访问: 由于原始类型数据的值直接存储在栈中,因此可以迅速访问和操作这些数据。这样的存储方式使得原始类型的数据在内存中的布局相对简单,提高了访问速度。
引用类型(Reference Types):
- 存储在堆空间: 引用类型的数据值(比如对象、数组、函数等)通常是动态大小的,它们的值存储在堆内存中。堆内存是一种相对较大但分配和释放速度较慢的内存区域。
- 灵活性: 引用类型的数据值可以包含不同数量和类型的属性,因此其大小是动态变化的。将它们存储在堆内存中允许程序动态地分配和释放内存,提供了更大的灵活性。
- 变量存储的是地址: 变量不直接存储引用类型的值,而是存储堆内存中该值的地址。这意味着在栈内存中存储的是引用,而实际数据位于堆内存中。
为什么要这么做:
- 原始类型的简单性: 原始类型的数据比较简单,大小固定,存储在栈内存中可以更快速地进行访问和操作。
- 引用类型的灵活性: 引用类型的数据结构可能非常复杂,大小不确定。将它们存储在堆内存中允许动态分配和释放内存,以应对动态的、复杂的数据结构。
- 引用类型的共享和复用: 由于引用类型的值存储在堆内存中,并且变量存储的是引用地址,多个变量可以共享同一个引用类型的值。这样可以提高内存利用率,避免重复存储相同的数据。