JavaScript 这段判空可以优化写法吗?

if (!this.formData.columnField1 || !this.formData.columnField2 || !this.formData.columnField3 || this
                    .formData.columnField4 || this.formData.columnField5 || this.formData.columnField6 || this.formData
                    .columnField7 || this.formData.columnField8) {
    uni.showToast({
        title: '项不可为空',
        icon: 'none'
    })
    return
}
阅读 8.2k
12 个回答

不用 eval ,直接用方括号语法拼接也是可以的。

for (var i = 1; i <= 8; i++) {
  if (!obj.formData['columnField' + i]) {
    uni.showToast({
      title: '第' + i + '项不可为空',
      icon: 'none'
    })
    return
  }
}

怎么会有人讨论那个12345,lz明显是在随便起了几个名字好吧

如果你的整张表格是走FormData的话,那么你可以用 formData.entries() 这种延展性好很多,不用担心表格名字变化导致程序错误。

var formData = new FormData();
formData.append('key1', 'value1');
formData.append('key2', '');

for (var pair of formData.entries()) {
        if(!pair[1]){
            console.log( pair[0] );  // 直接获得没有值的表格项
    }
}

使用Object.valuesArray.filter()的组合方式

可以用 eval:

var t1 = null
var t2 = null
var t3 = '11'

for (var i = 1; i <= 3; i++) {
    if (eval('!t' + i)) {
        console.log(i)
    }
}
for (var i = 1; i <= 8; i++) {
    if (eval('!this.formData.columnField' + i)) {
        uni.showToast({
            title: '第' + i + '项不可为空',
            icon: 'none'
        })
        return
    }
}

或者不用eval

for (var i = 1; i <= 8; i++) {
  if (obj.formData['columnField' + i]) {
    uni.showToast({
      title: '第' + i + '项不可为空',
      icon: 'none'
    })
    return
  }
}

有2个问题
后面几个字段漏了感叹号吗,提示文字是字段不能为空,但是if里面的判断规则,跟提示文字不太符合。
然后,0算有值还是没值,要特殊处理一下吗?

if (hasEmptyField(this.formData)) {
    uni.showToast({
        title: '项不可为空',
        icon: 'none'
    })
    return
}

function hasEmptyField(obj = {}) {
    return new Array(8).fill(0).some((_, index) => {
        return !obj[`columnField${index + 1}`]
    })
}

//  测试
hasEmptyField({
    columnField1: 1,
    columnField2: 1,
    columnField3: 1,
    columnField4: 1,
    columnField5: 1,
    columnField6: 1,
    columnField7: 1,
})  // true

hasEmptyField({
    columnField1: 1,
    columnField2: 1,
    columnField3: 1,
    columnField4: 1,
    columnField5: 1,
    columnField6: 1,
    columnField7: 1,
    columnField8: 1,
})  // false

一般来说就会用UI库提供的表单校验来做。如果真的UI库都不准备引入的话,可以考虑这样。

<script>
export default {
  data(){
    return {
      formData:{},
      fields: ['columnField1', 'columnField2',...]
    }
  },
  methods:{
    onValidEmpty(){
      return this.fields.every(field => !!this.formData[field] || this.formData[field] === 0)
    }
  }
}

或者在 formData 里面默认声明好全部属性,用 Object.keys 来获取全部字段名

<script>
export default {
  data(){
    return {
      formData:{
        columnField1:'',
        columnField2:'',
        columnField3:'',
        ....
      },
    }
  },
  methods:{
    onValidEmpty(){
      // 全部属性值都不为空则通过校验
      return Object.keys(this.formData).every(field => !!this.formData[field] || this.formData[field] === 0 )
    }
  }
}

所以另外一个角度,如果说 formData 所有的属性都需要填写,那么就可以在简写一下。

<script>
export default {
  data(){
    return {
      formData:{
        columnField1:'',
        columnField2:'',
        columnField3:'',
        ....
      },
    }
  },
  methods:{
    onValidEmpty(){
      // 任一属性值为空则返回 false
      return Object.value(this.formData).some(field => !this.formData[field] && this.formData[field] !== 0)
    }
  }
}

如果还要去除空格的话,按照业务场景判断加入 .trim() 即可。

@内了个裤 说的对,如果键名没有规律就不可能用循环来判断。
我觉得应该找个地方把所有判断项维护起来,后面再做逻辑:

const judges = [
    a => !a.formData.columnField1,
    a => !a.formData.columnField2,
    a => !a.formData.columnField3,
    a => a.formData.columnField4,
    a => a.formData.columnField5,
    a => a.formData.columnField6,
    a => a.formData.columnField7,
    a => a.formData.columnField8,
]
if (judges.some(fn => fn(this))) {
    uni.showToast({
        title: '项不可为空',
        icon: 'none'
    })
    return
}

你可参考一下,我这判断的是对象中的值至少有两个不为空出现提示

if (Object.values(searchForm).filter(v => v !== '' && v !== null).length < 2) {
        this.$message({
          message: '除消息类型外,请选择至少一个选项查询',
          type: 'warning'
        })
        this.isdisabled = false
        this.total = 0
        return false
      }

可以用switch true写

switch(true) {
  case !this.formData.columnField1:
  case !this.formData.columnField2:
  case !this.formData.columnField3:
  case !!this.formData.columnField4:
  case !!this.formData.columnField5:
  case !!this.formData.columnField6:
  case !!this.formData.columnField7:
  case !!this.formData.columnField8:
    uni.showToast({
        title: '项不可为空',
        icon: 'none'
    })
    return;
  default: break;
}

表示case项里面有一个是true则执行后续代码,坏处是多了一次取反操作,好处是看起来好看

  const formData = {
    columnField1: '',
    columnField2: '',
    columnField3: '',
    a: 1,
    b: 2
  }

  const columnFieldHasEmpty = Object.entries(formData).some(([key, val]) => {
    if (/columnField(\d)/.test(key)) {
      return !val
    } else {
      return false
    }
  })

  if (columnFieldHasEmpty) {
    alert('项不可为空')
  }

可以使用下面的写法来改善上述判空的写法:

// 获取项的数量
const fields = Object.keys(this.formData).length
// 遍历判断项是否为空
for (let i = 0; i < fields; i++) {
    if (!this.formData[`columnField${i + 1}`]) {
        uni.showToast({
            title: '项不可为空',
            icon: 'none'
        })
        return
    }
}

使用上述优化的写法,可以避免使用长而繁琐的 if 语句,更加便于维护代码。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题