javascript - 闭包返回数组/对象暴露了它的词法上下文:在 JavaScript 中处理的最佳方法?
问题描述
我想这可能是重复的,但我还没有找到解释。
这是我的示例代码:
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()
.
我的问题是:这是处理这个问题的正确方法吗?有没有更好的方法?可能我没有正确理解发生了什么......
解决方案
const makeCalendar = () => {
const calendar = {};
calendar.xmas = ['December', 25];
calendar.newYear = ['January', 1];
return (day) => JSON.parse(JSON.stringify(calendar))[day];
}
如果日历对象变得非常大,则不是最好的,但仍然有效。在那种情况下,甚至JSON.parse(JSON.stringify(calendar[day]))
会起作用。
诀窍是进行 parse 和 stringify 将创建原始对象的新副本,因此原始对象不会受到任何影响。当然,您可以使用其他方法来克隆对象,您可以在此处找到更多信息:在 JavaScript 中深度克隆对象的最有效方法是什么?
小提琴:http: //jsfiddle.net/briosheje/317hg6fb/
推荐阅读
- python - 如何将带有空字符的字符串从 C++ DLL 返回到 Python?
- laravel - 当我使用 url 在远程服务器上配置 apache2 时出现问题
- javascript - 如何使用单个变量作为多个键修改嵌套值
- swift - 如何在 swiftUI 中正确使用 MVVM?
- django - Nginx 返回 301 https://$server_name$request_uri; 重定向过多
- facebook - 如何通过链接打开 Instagram 搜索页面?
- javascript - 如何在数组中查找特定的数据行
- mysql - Flask Sqlalchemy,字段没有默认值
- ios - 我的 UIDatePicker 没有出现正确的格式
- mongodb - 如何知道 Heroku 使用的 IP 地址范围?