/**
* @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"
*/
2692. 使对象不可变
请你编写一个函数,该函数接收一个对象 obj
,并返回该对象的一个新的 不可变 版本。
不可变 对象是指不能被修改的对象,如果试图修改它,则会抛出错误。
此新对象可能产生三种类型的错误消息。
`Error Modifying: ${key}`
。`Error Modifying Index: ${index}`
。`Error Calling Method: ${methodName}`
。你可以假设只有以下方法能够改变数组: ['pop', 'push', 'shift', 'unshift', 'splice', 'sort', 'reverse']
。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} 解释:没有尝试进行修改,因此函数正常返回。
提示:
2 <= JSON.stringify(obj).length <= 105
原站题解
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" */