MST

星途 面试题库

面试题:JavaScript 代理对象的陷阱函数及应用场景

列举至少三个 JavaScript 代理对象的陷阱函数(trap),并详细阐述每个陷阱函数在实际开发中的应用场景,例如在数据验证、日志记录等方面如何使用。
45.0万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

以下是 JavaScript 代理对象的陷阱函数及其应用场景:

  1. get 陷阱函数
    • 应用场景 - 数据验证:当访问对象属性时,可以在 get 陷阱中对属性值进行验证。例如,有一个表示年龄的属性,可确保返回的年龄在合理范围内。
    const user = { age: 25 };
    const proxyUser = new Proxy(user, {
        get(target, property) {
            if (property === 'age' && typeof target[property] === 'number') {
                return Math.max(0, Math.min(120, target[property]));
            }
            return target[property];
        }
    });
    console.log(proxyUser.age); 
    
    • 应用场景 - 日志记录:记录属性访问操作,方便调试和性能分析。
    const obj = { name: 'John' };
    const proxyObj = new Proxy(obj, {
        get(target, property) {
            console.log(`Accessed property: ${property}`);
            return target[property];
        }
    });
    console.log(proxyObj.name); 
    
  2. set 陷阱函数
    • 应用场景 - 数据验证:在设置对象属性值时进行验证。比如设置密码时,验证密码长度是否符合要求。
    const account = {};
    const proxyAccount = new Proxy(account, {
        set(target, property, value) {
            if (property === 'password' && typeof value ==='string' && value.length >= 6) {
                target[property] = value;
                return true;
            }
            return false;
        }
    });
    proxyAccount.password = '123456'; 
    console.log(proxyAccount.password); 
    
    • 应用场景 - 自动更新关联数据:当一个属性值改变时,自动更新相关联的其他属性。例如购物车中商品数量改变时,自动更新总价。
    const cartItem = { price: 10, quantity: 1 };
    const proxyCartItem = new Proxy(cartItem, {
        set(target, property, value) {
            if (property === 'quantity' && typeof value === 'number' && value >= 0) {
                target[property] = value;
                target.totalPrice = target.price * target.quantity;
                return true;
            }
            return false;
        }
    });
    proxyCartItem.quantity = 2; 
    console.log(proxyCartItem.totalPrice); 
    
  3. has 陷阱函数
    • 应用场景 - 权限控制:判断对象是否具有某个属性时,根据权限决定是否允许访问。比如某些敏感属性只有特定角色才能访问。
    const data = { sensitiveData: 'confidential' };
    const proxyData = new Proxy(data, {
        has(target, property) {
            const hasAccess = true; // 假设这里是权限判断逻辑
            if (property ==='sensitiveData' &&!hasAccess) {
                return false;
            }
            return property in target;
        }
    });
    console.log('sensitiveData' in proxyData); 
    
    • 应用场景 - 模拟虚拟属性:即使对象实际没有某个属性,也可以通过 has 陷阱返回 true,模拟该属性存在。常用于提供统一的接口风格。
    const myObj = {};
    const proxyMyObj = new Proxy(myObj, {
        has(target, property) {
            if (property === 'virtualProperty') {
                return true;
            }
            return property in target;
        }
    });
    console.log('virtualProperty' in proxyMyObj); 
    
  4. deleteProperty 陷阱函数
    • 应用场景 - 数据保护:防止删除某些关键属性。例如,系统配置对象中的核心配置属性不允许被删除。
    const config = { apiKey: '12345' };
    const proxyConfig = new Proxy(config, {
        deleteProperty(target, property) {
            if (property === 'apiKey') {
                return false;
            }
            return true;
        }
    });
    delete proxyConfig.apiKey; 
    console.log(config.apiKey); 
    
    • 应用场景 - 清理关联数据:当删除某个属性时,自动清理相关联的其他数据。比如删除购物车中的商品时,同时清理该商品的相关缓存数据。
    const cart = { item1: { name: 'Product 1' } };
    const proxyCart = new Proxy(cart, {
        deleteProperty(target, property) {
            if (delete target[property]) {
                // 假设这里有清理缓存的逻辑
                console.log(`Deleted item and cleared related cache for ${property}`);
                return true;
            }
            return false;
        }
    });
    delete proxyCart.item1;