MST

星途 面试题库

面试题:结合JavaScript属性特性优化复杂业务逻辑的设计模式

假设你正在开发一个复杂的JavaScript应用,其中有多个模块需要共享一些全局状态数据。这些数据需要根据不同的运行环境和用户权限进行不同的访问控制。请基于JavaScript属性特性设计一套完整的设计模式,确保数据的安全性、可维护性和高效性。要求详细描述设计思路,包括如何利用属性特性实现细粒度的权限控制,以及如何在不同模块间进行状态共享和管理,同时给出关键代码示例及解释。
42.5万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 利用闭包封装状态:通过闭包将全局状态数据封装在一个函数内部,对外只暴露特定的访问和修改方法,这样可以防止外部直接访问和修改状态,提高数据安全性。
  2. 属性特性实现权限控制:使用JavaScript的属性特性(如Object.defineProperty())来定义访问器属性(getter和setter),在这些访问器中根据运行环境和用户权限进行相应的权限检查,实现细粒度的权限控制。
  3. 模块间状态共享:将封装状态和操作方法的对象作为一个单例模块导出,各个模块引入该模块来共享状态数据。

利用属性特性实现细粒度权限控制

通过Object.defineProperty()定义访问器属性时,在getter和setter中添加权限判断逻辑。例如,根据用户角色判断是否有权限获取或修改某个状态值。

不同模块间状态共享和管理

  1. 创建状态管理模块
// stateManager.js
let _state = {
    // 假设这里是全局状态数据
    sensitiveData: 'default value',
    userRole: 'guest'
};

const stateManager = (function () {
    function checkPermission(role, requiredRole) {
        // 简单的权限判断逻辑,实际应用中可能更复杂
        return role === requiredRole;
    }

    function getState() {
        return _state;
    }

    function setState(newState) {
        if (checkPermission(_state.userRole, 'admin')) {
            _state = { ..._state, ...newState };
        } else {
            throw new Error('Permission denied');
        }
    }

    // 使用属性特性定义访问器属性
    Object.defineProperty(_state, 'publicData', {
        get: function () {
            return this.sensitiveData;
        },
        set: function (value) {
            if (checkPermission(this.userRole, 'admin')) {
                this.sensitiveData = value;
            } else {
                throw new Error('Permission denied');
            }
        }
    });

    return {
        getState,
        setState
    };
})();

export default stateManager;
  1. 在其他模块中使用
// otherModule.js
import stateManager from './stateManager.js';

// 获取状态
const state = stateManager.getState();
console.log(state.publicData);

// 修改状态(只有admin角色能修改)
try {
    stateManager.setState({ sensitiveData: 'new value' });
} catch (error) {
    console.error(error.message);
}

代码解释

  1. stateManager模块
    • 使用闭包将_state数据和操作方法封装起来,外部无法直接访问和修改_state
    • checkPermission方法用于简单的权限判断。
    • getState方法返回当前状态对象,setState方法用于更新状态,但会进行权限检查。
    • 使用Object.defineProperty_state对象定义了publicData访问器属性,在getter和setter中进行权限控制。
  2. otherModule模块:通过导入stateManager模块来获取和修改共享状态数据,在操作过程中会触发权限控制逻辑。