返回介绍

solution / 2600-2699 / 2692.Make Object Immutable / README_EN

发布于 2024-06-17 01:03:01 字数 4688 浏览 0 评论 0 收藏 0

2692. Make Object Immutable

中文文档

Description

Write a function that takes an object obj and returns a new immutable version of this object.

An immutable object is an object that can't be altered and will throw an error if any attempt is made to alter it.

There are three types of error messages that can be produced from this new object.

  • Attempting to modify a key on the object will result in this error message: `Error Modifying: ${key}`.
  • Attempting to modify an index on an array will result in this error message: `Error Modifying Index: ${index}`.
  • Attempting to call a method that mutates an array will result in this error message: `Error Calling Method: ${methodName}`. You may assume the only methods that can mutate an array are ['pop', 'push', 'shift', 'unshift', 'splice', 'sort', 'reverse'].

obj is a valid JSON object or array, meaning it is the output of JSON.parse().

Note that a string literal should be thrown, not an Error.

 

Example 1:

Input: 
obj = {
  "x": 5
}
fn = (obj) => { 
  obj.x = 5;
  return obj.x;
}
Output: {"value": null, "error": "Error Modifying: x"}
Explanation: Attempting to modify a key on an object resuts in a thrown error. Note that it doesn't matter that the value was set to the same value as it was before.

Example 2:

Input: 
obj = [1, 2, 3]
fn = (arr) => { 
  arr[1] = {}; 
  return arr[2]; 
}
Output: {"value": null, "error": "Error Modifying Index: 1"}
Explanation: Attempting to modify an array results in a thrown error.

Example 3:

Input: 
obj = {
  "arr": [1, 2, 3]
}
fn = (obj) => { 
  obj.arr.push(4);
  return 42;
}
Output: { "value": null, "error": "Error Calling Method: push"}
Explanation: Calling a method that can result in a mutation results in a thrown error.

Example 4:

Input: 
obj = {
  "x": 2,
  "y": 2
}
fn = (obj) => { 
  return Object.keys(obj);
}
Output: {"value": ["x", "y"], "error": null}
Explanation: No mutations were attempted so the function returns as normal.

 

Constraints:

  • obj is a valid JSON object or array
  • 2 <= JSON.stringify(obj).length <= 105

Solutions

Solution 1

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文