如何查看JavaScript/TypeScript变量的内存地址?关于传值与传引用的疑问
在现代JavaScript/TypeScript中获取变量内存地址 & 理解传值/传引用
嘿,这个问题问到点子上了——内存地址确实是搞清楚JS参数传递逻辑的核心钥匙,我来给你掰扯清楚:
1. 标准JS/TS里能直接获取内存地址吗?
答案是不行。
JavaScript(包括TypeScript,因为它只是JS的超集)是一门高层抽象语言,引擎(比如V8)帮我们全权管理内存分配、回收这些底层细节,并没有暴露直接读取变量内存地址的API。这么设计的原因很简单:
- 安全:暴露内存地址可能带来内存泄露、非法访问等风险;
- 抽象性:JS的核心设计就是让开发者不用关心底层内存,专注于业务逻辑。
2. 不用内存地址,怎么理解传值/传引用?
很多人会混淆JS的传递机制,其实准确来说:JS里只有「传值调用」,但这个「值」的类型分两种:
对于原始类型(string、number、boolean、null、undefined、symbol、bigint):传递的是值的副本。也就是说,函数拿到的是和外部变量完全独立的一个值,修改它不会影响外部的原始变量。
举个例子:let age = 25; function updateAge(newAge) { newAge = 30; } updateAge(age); console.log(age); // 还是25,因为函数里改的是副本对于引用类型(对象、数组、函数等):传递的是「指向对象的引用的副本」。你可以把这个引用想象成一个“内存地址的替身”——函数拿到的是这个替身的副本,所以它和外部变量的引用指向同一个内存里的对象。这时候修改对象的属性会影响外部,但如果给参数重新赋值一个新对象,就和外部没关系了(因为副本指向了新的对象地址)。
举个例子:let user = { name: "张三" }; function updateUser(u) { u.name = "李四"; // 修改的是同一个对象的属性,外部会受影响 u = { name: "王五" }; // 给副本引用赋值新对象,和外部无关 } updateUser(user); console.log(user.name); // 输出「李四」
3. 有没有间接方式模拟“内存地址”?
如果只是为了区分不同对象是不是同一个(即是否指向同一块内存),可以用WeakMap给每个对象绑定一个唯一标识,当作“伪内存地址”:
const objIdentifier = new WeakMap(); let idCounter = 0; function getUniqueId(obj) { if (objIdentifier.has(obj)) { return objIdentifier.get(obj); } const newId = ++idCounter; objIdentifier.set(obj, newId); return newId; } const objA = {}; const objB = objA; const objC = {}; console.log(getUniqueId(objA)); // 1 console.log(getUniqueId(objB)); // 1(和objA是同一个对象) console.log(getUniqueId(objC)); // 2(新对象)
注意:这不是真正的内存地址,只是对象的唯一标识,而且WeakMap不会阻止垃圾回收,不会造成内存泄露,是比较安全的方式。
内容的提问来源于stack exchange,提问作者SAURABH
相关产品推荐
相关产品推荐

