这一页是JS 最核心的内存模型,搞懂它,后面闭包、引用赋值、传参改原对象全通了。一个比喻:堆 = 真实的房子(数据本体),栈 = 你口袋里的钥匙(只放门牌号)。
| 放什么 | 特点 | |
|---|---|---|
| 栈(口袋) | 数字/文字等小值、还有房门钥匙 | 小、快,函数用完自动清空 |
| 堆(小区) | 对象、数组、函数本体(房子) | 大,靠垃圾回收定期清理 |
数字、文字、真假这些小东西,直接放在口袋里。写 b = a,就是把 a 的东西复印一份给 b,从此两人各管各的。
let a = 10; let b = a; // 把10复印一张给b,从此各管各 b = 20; // 改b console.log(a); // a还是10,没被影响
如果你写 obj2 = obj1 以为复印了一个新对象,就会踩坑。因为对象住在堆里,口袋里只放钥匙。= 是又配了一把钥匙指向同一间房。改 obj2 的房里东西,obj1 开门一看也变了。
let obj1 = { name: "橘子" };
let obj2 = obj1; // 又配了一把钥匙进同一间房
obj2.name = "猫咪"; // 用obj2钥匙把名字改了
console.log(obj1.name); // 开门一看也变成"猫咪"
function changeName(obj) {
obj.name = "修改了"; // 拿着传进来的钥匙进房改
}
let cat = { name: "小桔子" };
changeName(cat); // 把cat的钥匙交给函数
console.log(cat.name); // 外面的名字也变成"修改了"
① 用在哪:传对象给函数、复制一份配置再改、调试为什么改 A 结果 B 也变了。
② 常见坑:obj2 = obj1 以为复制,结果改一处全变;函数里改对象外面跟着变。
③ 怎么解决:记住对象/数组传的是钥匙;要独立就 {...obj} 或 [...arr] 先复制。