javascript - 返回数组/对象的闭包公开其词法上下文 : best way to tackle in JavaScript?

标签 javascript closures

我想这可能是重复的,但我还无法找到解释。

这是我的示例代码:

const makeCalendar = () => {
  const calendar = {};

  calendar.xmas = ['December', 25];
  calendar.newYear = ['January', 1];

  return (day) => calendar[day];
}

calendar = makeCalendar();
const xmasArray = calendar('xmas');

console.log(calendar('xmas')); // [ 'December', 25 ]

xmasArray[1]++;

console.log(calendar('xmas')); // [ 'December', 26 ]

由于 xmasArray 的元素是可变的,我可以更改 makeCalendar() 范围内的变量,从而破坏它返回的闭包。我发现解决这个问题的唯一方法是返回一个匿名数组 [...calendar[day]](而不是 calendar[day]),然后阻塞makeCalendar() 中的访问。

我的问题是:这是处理这个问题的正确方法吗?有更好的方法吗?可能我没有正确理解发生了什么......

最佳答案

一种选择是使用 Object.freeze 禁止赋值给数组中的任何项目:

const makeCalendar = () => {
  const calendar = {
    xmas: ['December', 25],
    newYear: ['January', 1]
  };
  Object.values(calendar).forEach(arr => Object.freeze(arr));
  return (day) => calendar[day];
}

calendar = makeCalendar();
const xmasArray = calendar('xmas');

console.log(calendar('xmas'));

xmasArray[1]++;

console.log(calendar('xmas'));

请注意,这种尝试分配将在严格模式下抛出错误:

Uncaught TypeError: Cannot assign to read only property '1' of object '[object Array]

关于javascript - 返回数组/对象的闭包公开其词法上下文 : best way to tackle in JavaScript?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53775748/

相关文章:

javascript - 当 Canvas 响应时,拖动不会检测到放下

javascript - 如何使用 Angular 将逗号分隔的字符串转换为 json 对象类型

jQuery-UI 对话框内存泄漏

javascript - 使用 Javascript 闭包将附加数据传递给 API 回调函数

javascript - 在 webbrowser 控件中在 javascript 和 VB .net 之间共享变量

javascript - d3.json() 支持身份验证吗?如果没有,还有哪些其他 JavaScript 选项可用于 JSON 检索?

javascript - 如何使用 jquery 在单击的行下方添加新行

javascript - JavaScript 中的调用堆栈变量

javascript - for 循环中的函数的行为类似于闭包

java - Groovy中的apply()方法语法