js原始类型 vs 对象

21 阅读3分钟

一、js中,变量名并不真正“存储”值,而是存储一个“引用”(指向一个内存位置)

JavaScript 的变量 = “名字(标识符)指向一个内存地址”

但它和 C/C++ 的变量模型非常不一样。

我帮你用你已经懂的 C 语言视角来对比解释👇


1. JS 中的变量是什么?

在 JavaScript 中:

变量名并不真正“存储”值,而是存储一个“引用”(指向一个内存位置)。 所以,const类型绑定了call stack里某块内存,无法指向其它内存

例如:

let a = 10;

JS 在内存里表现为:

a  ───►  [ 10 ]

如果是对象:

let obj = { x: 1 };

内存是:

obj ───►   (地址0x001)
              │
              ▼
           { x: 1 }

变量存放的是“引用 / 指针-like 地址”,不是值本身。


2. 和 C/C++ 的对比

⭕ 基本类型的比较

C:

int a = 10;

内存:

[ a: 10 ]  // 变量直接存值

JS:

let a = 10;

内存:

a ───► [10]

区别:

语言变量存储的是什么?
C/C++变量本身存放值本体
JS变量存的是“指针(引用)”,值放在别处

⭕ 对象(引用类型)的比较

C++:

Person p(20);
Person q = p;   // 拷贝一份

q 会复制一份新的对象。

JS:

let p = { age: 20 };
let q = p;  // 不会复制对象

内存:

p ──┐
    ▼
  { age: 20 }
    ▲
q ──┘

两者指向同一个地址

→ 改 p / q 的内部内容会互相影响

这是 JS 和 C 最大的差异之一。


🧠 3. 那 const 为什么不能重新赋值?

因为:

const 变量名 = 某个地址;

JS 禁止你改变这个 变量名→地址 的绑定。

但允许改变“地址里的内容”。


🧠 4. 为什么说 JS 没有“真正的值类型变量”概念?

因为所有变量(包括基本类型)本质上都通过引用来实现访问

区别只是:

  • 基本类型所在的内存区域不可共享,所以拷贝时拷贝的是值

  • 引用类型的地址可以共享,所以会产生“两个变量名指向同一对象”的情况

但 JS 内部机制统一:

变量只是标签 → 指向某个内存块

一句话总结:

JS 中的变量永远“指向”一个内存位置(引用语义),

与 C/C++ 的“变量就是内存” 有本质不同。

二、原始类型 VS 对象类型

原始类型(integer、null, string等)存储在call stack里,对象(对象、数组,js中数组也是一种对象类型)存储在heap里,因为对象可能很大,call stack内存较小。call stack有一块内存存储对象在heap里的地址(存储该对象的引用),从而访问对象。

//原始类型:
let age = 23; //指向某一块内存,地址为a1,该内存存23
let oldAge = age; //指向内存a1
//change age,但oldAge不应该改变,否则就失去了复制变量的意义,所以:
age = 30; //js会新增一块内存a2, 存30,age改成指向该内存地址a2.
age = 35; //改变age指向的内存a2存的值为35.
console.log(age); //35
console.log(oldAge); //23
//change oldAge:
oldAge = 40;
console.log(age); //30
console.log(oldAge); //40

//对象类型里的属性是引用类型,
//当你复制一个对象给另一个变量时,js也只是新建这个变量指向相同的的call stack内存,这个内存存储了该对象的引用。

IMG_0423.JPG