问题描述
我有一个包含用户信息值(例如姓名、联系人和地址)的表单。地址有效性的逻辑是“全有或全无”条件——这意味着如果用户没有为地址输入输入任何值,那么它是有效的,但如果他们输入一个地址输入(即街道名称)但缺少其他东西(即邮政)则无效。
表单数据的结构如下:
form: {
first_name: {
value: ‘’,valid: false,},last_name: {
value: ‘’,//... more values here
street: {
value: ‘’,city: {
value: ‘’,state: {
value: ‘’,postal: {
value: ‘’,country: {
value: ‘’,}
以下是用于测试该逻辑的代码,如果street
、city
、state
、postal
和country
都为空,那么一切都是有效的。但是如果其中一个被赋予了值,那么其余的也必须被提供
const addressKeys = ['street','city','state','postal','country']
let isAddValid = form[addressKeys.pop()].value !== ''
for(const key of addressKeys) {
isAddValid = !(isAddValid ^ form[key].value === ''))
}
console.log('is address valid?',isAddValid)
这将正确返回有效值(当输入所有值时,如果至少提供一个值时缺少一个或多个值),但它没有正确评估所有空值(未提供输入值)是否有效。我错过了什么?
解决方法
您可以使用 .every()
来检查 addressKeys
中的所有键是否为空,或者 (||
) 都为非空。
const form = { first_name: { value: '',valid: false,},last_name: { value: '',street: { value: '',city: { value: '',state: { value: '',postal: { value: '',country: { value: '',};
const addressKeys = ['street','city','state','postal','country'];
const valid = addressKeys.every(key => form[key].value === '') || addressKeys.every(key => form[key].value !== '');
console.log(valid);
这乍一看似乎效率低下,但此代码在 .every()
方法调用和 ||
操作中都会短路。这意味着如果所有值实际上都是空的,则无需检查它们是否都包含值,由于 ||
的工作原理,JS 将为我们跳过数组的额外迭代。类似地,如果除 state
之外的所有对象都包含空值,则第一个 .every()
调用将在发现 state
非空后立即停止,并且不会检查任何进一步的值,因为它已经知道它没有通过测试。然后当第二个 .every()
调用进行检查时,它会立即看到 street
包含一个空值,并且也会短路,立即返回 false
而无需遍历整个数组。
我认为 for 循环中的 xor 不正确,也许应该这样做:
function check(form) {
const addressKeys = ['street','country'];
let isAddValid = form[addressKeys.pop()].value !== '';
// check others,if others is different from isAddVaild; return false;
for(const key of addressKeys) {
if (isAddValid ^ form[key].value !== '') {
return false;
}
}
return true;
}
console.log('is address valid?',check(form))