列表

详情


2692. 使对象不可变

请你编写一个函数,该函数接收一个对象 obj ,并返回该对象的一个新的 不可变 版本。

不可变 对象是指不能被修改的对象,如果试图修改它,则会抛出错误。

此新对象可能产生三种类型的错误消息。

obj 是一个有效的 JSON 对象或数组,也就是说,它是 JSON.parse() 的输出结果。

请注意,应该抛出字符串字面量,而不是 Error 对象。

 

示例 1:

输入:
obj = {
  "x": 5
}
fn = (obj) => { 
  obj.x = 5;
  return obj.x;
}
输出:{"value": null, "error": "Error Modifying: x"}
解释:试图修改对象的键会导致抛出错误。请注意,是否将值设置为与之前相同的值并不重要。

示例 2:

输入: 
obj = [1, 2, 3]
fn = (arr) => { 
  arr[1] = {}; 
  return arr[2]; 
}
输出:{"value": null, "error": "Error Modifying Index: 1"}
解释:试图修改数组会导致抛出错误。

示例 3:

输入:
obj = {
  "arr": [1, 2, 3]
}
fn = (obj) => { 
  obj.arr.push(4);
  return 42;
}
输出:{ "value": null, "error": "Error Calling Method: push"}
解释:调用可能导致修改的方法会导致抛出错误。

示例 4:

输入:
obj = {
  "x": 2,
  "y": 2
}
fn = (obj) => { 
  return Object.keys(obj);
}
输出:{"value": ["x", "y"], "error": null}
解释:没有尝试进行修改,因此函数正常返回。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
/** * @param {Object|Array} obj * @return {Object|Array} immutable obj */ var makeImmutable = function(obj) { }; /** * const obj = makeImmutable({x: 5}); * obj.x = 6; // throws "Error Modifying x" */

javascript 解法, 执行用时: 388 ms, 内存消耗: 62.9 MB, 提交时间: 2023-10-15 14:59:10

/**
 * @param {Object | Array} obj
 * @return {Object | Array} immutable obj
 */

const handler = {
    get(target,p){
        if(methods[p]){
            return ()=>{
                throw `Error Calling Method: ${p}` 
            }
            
        }
        return target[p]
    },   

    set (target,p){
        if(Array.isArray(target)){
            throw `Error Modifying Index: ${p}`
        }
        throw `Error Modifying: ${p}`
    }
}
const methods  =  {
    'pop':true,
    'push':true,
    'shift':true,
    'unshift':true,
    'splice':true,
    'sort':true,
    'reverse':true
}
var makeImmutable = function(obj) {
    
    let newObj 
    const type = Object.prototype.toString.call(obj)
   
    if(type ==='[object Object]'){
        newObj = {}
        for(key of Object.keys(obj)){
            newObj[key] = makeImmutable(obj[key])
        }
    }else if(type ==='[object Array]'){
        newObj = []
        
        for(let i = 0;i<obj.length;i++){
             newObj[i] = makeImmutable(obj[i])
        }
    }else{
        return obj
    }
    return new Proxy(newObj,handler)
};

/**
 * const obj = makeImmutable({x: 5});
 * obj.x = 6; // throws "Error Modifying x"
 */

typescript 解法, 执行用时: 392 ms, 内存消耗: 62.5 MB, 提交时间: 2023-10-15 14:56:19

type Obj = Array<any> | Record<any, any>;

function makeImmutable(obj: Obj): Obj {
    let arrayHandler: ProxyHandler<Array<any>> = {
        set: (_, p) => {
            throw `Error Modifying Index: ${String(p)}`
        },
    }
    let commonHandler: ProxyHandler<Record<any, any>> = {
        set: (_, p) => {
            throw `Error Modifying: ${String(p)}`
        }
    }
    let mutArrayHandler: ProxyHandler<Function> = {
        apply: (target) => {
            throw `Error Calling Method: ${target.name}`
        }
    }
    let addProxy = (obj: Obj) => {
        const mutableFn = ['pop', 'push', 'shift', 'unshift', 'splice', 'sort', 'reverse']
        for (let p in obj) {
            if (typeof obj[p] === 'object' && obj[p] !== null) {
                obj[p] = addProxy(obj[p])
            }
        }
        if (Array.isArray(obj)) {
            mutableFn.forEach((fn) => {
                obj[fn] = new Proxy(obj[fn], mutArrayHandler)
            })
            return new Proxy(obj, arrayHandler)
        }
        return new Proxy(obj, commonHandler)
    }
    return addProxy(obj)
};

/**
 * const obj = makeImmutable({x: 5});
 * obj.x = 6; // throws "Error Modifying x"
 */

上一题