WeakMap和WeakSet的核心机制是弱引用,其键或元素不会阻止垃圾回收,当对象仅被WeakMap/WeakSet引用时可被回收,从而避免内存泄漏;而Map和Set持有强引用,会阻止对象回收。根本区别在于引用强度:WeakMap/WeakSet用于关联元数据或标记对象,随对象生命周期自动管理;Map/Set用于持久存储数据,需手动管理。WeakMap适合实现私有属性,通过模块作用域闭包将实例作为键存储私有数据,外部无法访问且自动清理;WeakSet适用于标记场景,如跟踪已处理对象、防止重复遍历等,不存值只判属,二者均在对象生命周期管理中优于传统方案。

利用
WeakMap
WeakSet
Map
Set
WeakMap
WeakSet
WeakMap
WeakSet
Map
Set
要利用
WeakMap
WeakSet
WeakMap
想象一下,我们想为一个类的实例存储一些外部无法直接访问的数据。我们可以在模块作用域内声明一个
WeakMap
WeakMap
WeakMap
WeakMap
// module scope
const _privateData = new WeakMap();
class MyClass {
constructor(publicProp, privateProp1, privateProp2) {
this.publicProp = publicProp;
// 将私有数据存储在WeakMap中
_privateData.set(this, {
privateProp1: privateProp1,
privateProp2: privateProp2,
_internalCounter: 0 // 甚至可以有内部状态
});
}
getPrivateProp1() {
const privateProps = _privateData.get(this);
return privateProps ? privateProps.privateProp1 : undefined;
}
incrementCounter() {
const privateProps = _privateData.get(this);
if (privateProps) {
privateProps._internalCounter++;
console.log(`Internal counter for this instance: ${privateProps._internalCounter}`);
}
}
// 尝试直接访问私有属性会失败
// console.log(instance._privateData); // undefined
}
const instance1 = new MyClass("Hello", "Secret1", "Hidden1");
const instance2 = new MyClass("World", "Secret2", "Hidden2");
console.log(instance1.publicProp); // "Hello"
console.log(instance1.getPrivateProp1()); // "Secret1"
instance1.incrementCounter(); // Internal counter for this instance: 1
instance1.incrementCounter(); // Internal counter for this instance: 2
console.log(instance2.getPrivateProp1()); // "Secret2"
instance2.incrementCounter(); // Internal counter for this instance: 1
// 外部无法直接访问_privateData这个WeakMap,也无法通过实例访问私有属性
// console.log(_privateData.get(instance1)); // 在模块外部是访问不到_privateData的这个模式确保了私有数据的封装性,同时利用
WeakMap
在我看来,理解
WeakMap
WeakSet
Map
Set
具体来说:
WeakMap
WeakSet
WeakMap
WeakSet
WeakMap
WeakSet
Map
Set
Map
Set
Map
Map
所以,核心区别在于:
WeakMap
WeakSet
Map
Set
说实话,在JavaScript中实现“真正”的私有属性一直是个挑战。从早期的约定俗成(下划线前缀)、闭包、Symbol,到后来的私有类字段(
#
WeakMap
利用
WeakMap
WeakMap
WeakMap
实现步骤和原理:
WeakMap
WeakMap
WeakMap
this
WeakMap
WeakMap
_privateData.get(this)
MyClass
WeakMap
WeakMap
代码示例(更贴近实际场景):
// user-profile.js 模块
const _userData = new WeakMap();
class UserProfile {
constructor(id, username, email) {
this.id = id; // 公开属性
this.username = username; // 公开属性
// 私有数据,只有UserProfile实例和这个模块内部能访问
_userData.set(this, {
email: email,
lastLogin: null,
_sessionToken: Math.random().toString(36).substring(2) // 更私密的内部状态
});
}
getEmail() {
const data = _userData.get(this);
return data ? data.email : 'N/A';
}
updateLastLogin() {
const data = _userData.get(this);
if (data) {
data.lastLogin = new Date();
console.log(`User ${this.username} last logged in at: ${data.lastLogin}`);
}
}
// 模拟一个内部方法,需要访问私有token
_verifySession() {
const data = _userData.get(this);
if (data && data._sessionToken) {
console.log(`Verifying session with token: ${data._sessionToken}`);
return true;
}
return false;
}
}
// 导出类
export default UserProfile;
// 在另一个文件 app.js 中
// import UserProfile from './user-profile.js';
// const user1 = new UserProfile(1, 'Alice', 'alice@example.com');
// console.log(user1.username); // Alice
// console.log(user1.getEmail()); // alice@example.com
// user1.updateLastLogin(); // User Alice last logged in at: ...
// // 尝试访问私有数据:
// // console.log(user1.email); // undefined
// // console.log(_userData.get(user1)); // ReferenceError: _userData is not defined (如果_userData在模块外不可访问)
// let user2 = new UserProfile(2, 'Bob', 'bob@example.com');
// // 假设user2对象不再被引用
// user2 = null; // 现在Bob的UserProfile实例可以被垃圾回收了
// // 此时,WeakMap中关于user2的条目也会自动被清理,无需手动操作这种模式在封装性和内存效率之间取得了很好的平衡,是我个人在需要严格私有化且关心内存时,会优先考虑的方案。
WeakSet
WeakMap
WeakSet的独特作用场景:
WeakSet
WeakSet
WeakSet
WeakSet
WeakMap与WeakSet的应用边界:
理解它们各自的边界,其实就是理解“关联数据”和“标记集合”的区别。
WeakMap
WeakSet
简单来说,如果你需要为每个对象存储独有的值,那就用
WeakMap
WeakSet
Map
Set
以上就是如何利用WeakMap和WeakSet实现私有属性,以及它们与普通Map和Set在内存管理上的区别?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号