Pavan 的回答很好,但要使其在自动化测试中可测试:
// I would name these fields in your API
// by making the constructor take an object.
// Capitalise the name to signal that it can be newed
function Member({id, password}) {
this.id = id;
this.pwd = password
}
// Name the array for what it is
const members = [
new Member({id: "m001", password: "123"}),
new Member({id: "m002", password: "123"}),
new Member({id: "m031", password: "123"})
]
const editInBrowserFn = member => JSON.parse(window.prompt("want to edit values?", JSON.stringify(member)));
const updateMembers = editFn => array => array.map(editFn)
// To get an update
const updatedMembers = updateMembers(editInBrowserFn)(members)
console.log(updatedMembers)
// You can now test it by making an testing editFn that doesn't need user interaction
const testEditFn = m => new Member({id: m.id, password: 'test'})
const testMembers = updateMembers(testEditFn)(members)
console.log(testMembers)
请参阅this article 了解有关此方法的深入说明。
要这样做,您需要将其移出全局范围。这是一个很好的发展纪律。作为第一步,您可以在全局范围内创建一个包含最新成员列表的对象:
const Members = (() => {
let _members = []
return {
setMembers: members => _members = [...members],
getMembers: () => [..._members]
}
})()
现在更新成员的方式是这样的:
const updateFn = updateMembers(editInBrowser)
function updatePasswords() {
const members = Members.getMembers()
Members.setMembers(updateFn(members))
}
现在没有什么可以意外删除或改变成员数组,从而消除了错误的表面区域。
这就是 React setState 的设计方式。它受到函数式编程思想和不变性的启发。
您可能希望只更新一个成员,所以:
const Members = (() => {
let _members = []
return {
setMembers: members => _members = [...members],
getMembers: () => [..._members],
updateMember: updated =>
this.members = _members.map(m =>
m.id === updated.id ? updated : m)
}
})()
现在你所有的数组突变都在一个地方,你只需要在那里让它没有错误。否则,您的全局状态会暴露出来,您必须修复与其相关的所有错误。没有这个,你所有的调用函数都负责正确管理应用程序的全局状态。复杂。
将复杂性集中在一处。
我写了一篇文章和商店的完整实现(40行代码)here。