如何在JavaScript中创建不透明对象?隐藏对象部分属性
如何创建隐藏部分属性的对象(类似Path2D控制台输出效果)
要实现像Path2D那样在控制台仅显示干净的对象结构、隐藏内部属性的效果,主要有以下几种实用方案:
1. ES6类私有字段(推荐现代场景)
使用#前缀定义类的私有字段,这类字段完全对外隐藏,控制台不会显示,也无法在类外部直接访问:
class CustomPath { // 私有字段,控制台不会显示 #points = []; #currentPosition = { x: 0, y: 0 }; constructor() { // 公共属性(可选,会显示在控制台) this.type = 'CustomPath'; } // 对外暴露的方法 addPoint(x, y) { this.#points.push({ x, y }); this.#currentPosition = { x, y }; } getCurrentPoint() { return { ...this.#currentPosition }; } } const path = new CustomPath(); path.addPoint(10, 20); console.log(path); // 输出:CustomPath { type: 'CustomPath' }
2. Object.defineProperty 标记属性为非可枚举
通过设置enumerable: false,让属性不会被for...in遍历,控制台默认也不会显示这类属性:
function CustomPath() { // 私有属性(非可枚举) const points = []; const currentPosition = { x: 0, y: 0 }; // 公共属性(可枚举,会显示) this.type = 'CustomPath'; // 用defineProperty挂载方法或隐藏属性 Object.defineProperty(this, 'addPoint', { value: function(x, y) { points.push({ x, y }); currentPosition.x = x; currentPosition.y = y; }, enumerable: false // 方法也可以隐藏 }); Object.defineProperty(this, '_currentPosition', { get: function() { return { ...currentPosition }; }, enumerable: false // 访问器属性隐藏 }); } const path = new CustomPath(); path.addPoint(10, 20); console.log(path); // 输出:CustomPath { type: 'CustomPath' }
3. 使用Symbol作为属性名
Symbol类型的属性名不会出现在控制台的常规输出中,也不会被Object.keys()或for...in遍历到:
const POINTS = Symbol('points'); const CURRENT_POS = Symbol('currentPosition'); class CustomPath { constructor() { this.type = 'CustomPath'; this[POINTS] = []; this[CURRENT_POS] = { x: 0, y: 0 }; } addPoint(x, y) { this[POINTS].push({ x, y }); this[CURRENT_POS] = { x, y }; } getCurrentPoint() { return { ...this[CURRENT_POS] }; } } const path = new CustomPath(); path.addPoint(10, 20); console.log(path); // 输出:CustomPath { type: 'CustomPath' } // 只有通过Object.getOwnPropertySymbols才能拿到这些属性 console.log(Object.getOwnPropertySymbols(path)); // [Symbol(points), Symbol(currentPosition)]
4. WeakMap存储私有数据
把私有数据存到外部的WeakMap中,对象本身不挂载任何私有属性,控制台输出会非常干净:
const privateData = new WeakMap(); class CustomPath { constructor() { this.type = 'CustomPath'; // 把私有数据存在WeakMap里,键为当前实例 privateData.set(this, { points: [], currentPosition: { x: 0, y: 0 } }); } addPoint(x, y) { const data = privateData.get(this); data.points.push({ x, y }); data.currentPosition = { x, y }; } getCurrentPoint() { const data = privateData.get(this); return { ...data.currentPosition }; } } const path = new CustomPath(); path.addPoint(10, 20); console.log(path); // 输出:CustomPath { type: 'CustomPath' }
以上几种方案都能实现类似Path2D的控制台简洁输出效果,你可以根据项目的ES版本支持和实际需求选择合适的方式。
内容的提问来源于stack exchange,提问作者Meysam Ghorbani
相关产品推荐
相关产品推荐

