Skip to content
扫码开始移动端阅读

什么是魔数

936
需要≈
4.68
分钟
web

TIP

魔数(Magic Number),或称魔法值、魔术数字,是指在代码中出现但未解释的数字常量或字符串。几个月或几年后,你可能会忘记这些值的含义。让我们看看魔数到底是什么以及如何避免它们。

魔数的常见场景

在前端开发中,与后端定义接口时,经常使用一些约定好的数字或字符串来代表业务状态。例如,系统中可能用 01 来表示性别:

javascript
if (gender === '0') {
    // 做一些与女性相关的操作
}

if (gender === '1') {
    // 做一些与男性相关的操作
}

硬编码这种方式,不仅让其他开发者难以理解这些值的意义,还增加了出错的可能。每次使用时都需要注释,而且编辑器也无法提供联想和提示功能。

为什么要避免使用魔数

魔数代表了不好的编码习惯,缺点也很明显:

  • 难以理解:数值的意义不明确。
  • 维护困难:数值需要变动时,可能需要修改多个地方。

使用常量消除魔数

我们可以通过定义常量来避免魔数。例如:

javascript
const FEMALE = '0'; // 女性
const MALE = '1'; // 男性

if (gender === FEMALE) {
    // 做一些与女性相关的操作
}

if (gender === MALE) {
    // 做一些与男性相关的操作
}

这种方法不仅让代码更具可读性,还能利用编辑器的提示功能,避免拼写错误。

更复杂的例子:

🛒订单管理

假设我们有一个订单管理功能,不同的订单状态需要展示不同的操作按钮:

  • 待付款:0
  • 待发货:1
  • 待收货:2
  • 待评价:3

代码

vue
<template>
  <div class="container">
    <el-select v-model="form.status" style="margin-right: 20px">
      <el-option label="待付款" value="0"/>
      <el-option label="待发货" value="1"/>
      <el-option label="待收货" value="2"/>
      <el-option label="待评价" value="3"/>
    </el-select>
    <el-button type="primary" @click="handleSearch">查询</el-button>
    <hr>
    <el-table :data="orderList">
      <el-table-column prop="id" label="订单号"/>
      <el-table-column prop="address" label="收货地址"/>
      <el-table-column prop="phone" label="手机号"/>
      <el-table-column label="订单状态">
        <template #default="{row}">
          <span v-if="row.status === '0'">待付款</span>
          <span v-if="row.status === '1'">待发货</span>
          <span v-if="row.status === '2'">待收货</span>
          <span v-if="row.status === '3'">待评价</span>
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template #default="{row}">
          <el-button v-if="row.status === '0'" type="text">去付款</el-button>
          <el-button v-if="row.status === '1'" type="text">催发货</el-button>
          <el-button v-if="row.status === '2'" type="text">收货</el-button>
          <el-button v-if="row.status === '3'" type="text">去评价</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script setup>
import { reactive } from 'vue';

const form = reactive({ status: '3' });
const orderList = reactive([]);

function handleSearch() {
  setTimeout(() => {
    orderList.value = [
      { id: 202004000, address: '北京市', phone: 1311112223, status: '0' },
      { id: 202004001, address: '上海市', phone: 1311112223, status: '1' },
      { id: 202004002, address: '天津市', phone: 1311112224, status: '2' },
      { id: 202004003, address: '重庆市', phone: 1311112225, status: '3' }
    ].filter(item => item.status === form.status);
  }, 500);
}

handleSearch();
</script>

<style scoped>
.container {
  margin: 70px;
}
</style>

优化:消除魔数

首先,定义常量:

javascript
const STATUS = {
  PENDING_PAYMENT: '0',
  WAITING_FOR_DELIVERY: '1',
  WAITING_FOR_RECEIPT: '2',
  WAITING_FOR_EVALUATION: '3'
};

然后在代码中使用这些常量:

vue
<template>
    <el-table-column label="操作">
    <template #default="{row}">
        <el-button v-if="row.status === STATUS.PENDING_PAYMENT" type="text">去付款</el-button>
        <el-button v-if="row.status === STATUS.WAITING_FOR_DELIVERY" type="text">催发货</el-button>
        <el-button v-if="row.status === STATUS.WAITING_FOR_RECEIPT" type="text">收货</el-button>
        <el-button v-if="row.status === STATUS.WAITING_FOR_EVALUATION" type="text">去评价</el-button>
    </template>
    </el-table-column>
</template>

定义状态编码与文本的映射关系:

javascript
const STATUS_TEXT = {
  [STATUS.PENDING_PAYMENT]: '待付款',
  [STATUS.WAITING_FOR_DELIVERY]: '待发货',
  [STATUS.WAITING_FOR_RECEIPT]: '待收货',
  [STATUS.WAITING_FOR_EVALUATION]: '待评价'
};

在模板中使用:

vue
<template>
  <el-table-column label="订单状态">
    <template #default="{row}">
      {{ STATUS_TEXT[row.status] }}
    </template>
  </el-table-column>
</template>

结语

通过使用常量代替魔数,提高了代码的可读性和可维护性。虽然看起来增加了工作量,但在项目维护时间较长时,收益更高。坚持良好的编码习惯,才能写出更优雅、可靠的代码。

上次更新: