MST

星途 面试题库

面试题:JavaScript对象可扩展能力在复杂应用场景下的突破与优化

在一个大型JavaScript应用中,存在大量具有不同可扩展需求的对象,部分对象需要在特定条件下突破可扩展限制。请设计一个通用的解决方案,既能有效管理对象的可扩展性,又能保证系统性能和内存的合理使用。阐述设计思路并给出核心代码片段。
20.0万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 使用 Object.defineProperty 管理可扩展性:通过 Object.defineProperty 方法可以精确控制对象属性的特性,包括是否可扩展。这使得我们能够在创建对象时就明确其可扩展性规则。
  2. 引入一个管理器对象:用于集中管理对象的可扩展性,方便在特定条件下修改对象的可扩展状态。这样可以避免在代码中分散地设置对象的可扩展性,增强代码的可维护性。
  3. 性能和内存优化:尽量减少不必要的对象创建和属性操作,对于频繁访问的对象,可以缓存其可扩展性状态,避免重复查询。

核心代码片段

// 可扩展性管理器
const extensibilityManager = {
    objects: {},
    // 注册对象及其初始可扩展性
    registerObject: function (obj, isExtensible) {
        this.objects[obj] = {
            isExtensible: isExtensible,
            originalState: Object.getOwnPropertyDescriptors(obj)
        };
        Object.preventExtensions(obj);
        if (isExtensible) {
            Object.defineProperty(obj, Symbol('__isExtensible'), {
                value: true,
                enumerable: false,
                configurable: false
            });
        }
    },
    // 在特定条件下使对象可扩展
    makeExtensible: function (obj) {
        if (!this.objects[obj]) {
            throw new Error('Object not registered');
        }
        if (this.objects[obj].isExtensible) {
            Object.defineProperty(obj, Symbol('__isExtensible'), {
                value: true,
                enumerable: false,
                configurable: false
            });
            Object.defineProperty(obj, Symbol('__originalState'), {
                value: this.objects[obj].originalState,
                enumerable: false,
                configurable: false
            });
            Object.defineProperty(obj, Symbol('__restore'), {
                value: function () {
                    const originalState = this[Symbol('__originalState')];
                    Object.keys(originalState).forEach(key => {
                        Object.defineProperty(this, key, originalState[key]);
                    });
                    Object.preventExtensions(this);
                    Object.defineProperty(this, Symbol('__isExtensible'), {
                        value: false,
                        enumerable: false,
                        configurable: false
                    });
                },
                enumerable: false,
                configurable: false
            });
            Object.defineProperties(obj, {
                ...this.objects[obj].originalState,
                ...Object.getOwnPropertyDescriptors(obj)
            });
            Object.enhanceExtensions(obj);
        }
    },
    // 恢复对象到不可扩展状态
    restoreObject: function (obj) {
        if (!this.objects[obj]) {
            throw new Error('Object not registered');
        }
        if (this.objects[obj].isExtensible) {
            const restoreFunction = obj[Symbol('__restore')];
            if (restoreFunction) {
                restoreFunction.call(obj);
            }
        }
    }
};

// 示例用法
const myObject = {};
extensibilityManager.registerObject(myObject, true);

// 在特定条件下
if (someCondition) {
    extensibilityManager.makeExtensible(myObject);
    myObject.newProperty = 'new value';
} else {
    extensibilityManager.restoreObject(myObject);
}