个人所得税计算器 在线工具核心JS实现

这篇只讲功能层 JavaScript 实现。这个工具的核心思路是:把税率规则、五险一金规则、累计预扣法放进一个计算类里,输入 12 个月收入和扣除配置后,一次产出整年的月度明细。

在线工具网址:see-tool.com/text-charac...

工具截图:

1. 核心数据结构

计算器初始化时,先准备三类基础数据:

  • 累计预扣法税率表(含速算扣除数)
  • 城市社保/公积金缴费基数上下限
  • 每月减除费用(5000)
javascript 复制代码
class IncomeTaxCalculator {
  constructor() {
    // 累计预扣税率区间
    this.taxBrackets = [
      { min: -1, max: 36000, rate: 0.03, deduction: 0 },
      { min: 36000, max: 144000, rate: 0.10, deduction: 2520 },
      { min: 144000, max: 300000, rate: 0.20, deduction: 16920 },
      { min: 300000, max: 420000, rate: 0.25, deduction: 31920 },
      { min: 420000, max: 660000, rate: 0.30, deduction: 52920 },
      { min: 660000, max: 960000, rate: 0.35, deduction: 85920 },
      { min: 960000, max: Infinity, rate: 0.45, deduction: 181920 }
    ]

    // 每月减除费用
    this.monthlyDeduction = 5000
  }
}

这一步把规则常量和计算逻辑解耦,后续计算函数不需要硬编码税率数字。

2. 月度五险一金计算

月度扣除支持三种基数来源:

  • 按月工资
  • 单一自定义基数
  • 养老/医疗/失业/公积金分别设置基数

关键点在"实际基数"处理:要同时受用户输入、封顶线、保底线、当月工资四个条件约束。

javascript 复制代码
// 计算实际缴费基数
const getActualBase = (baseValue, capValue, floorValue, monthlyIncome) => {
  // 统一兜底,避免 NaN 和负数
  const safeBase = Math.max(0, baseValue || 0)
  const safeCap = Math.max(0, capValue || 0)
  const safeFloor = Math.max(0, floorValue || 0)

  // 先做上限约束:不能超过上限,也不能超过月薪
  let result = safeCap > 0
    ? Math.min(safeBase, safeCap, monthlyIncome)
    : Math.min(safeBase, monthlyIncome)

  // 再做下限约束
  if (safeFloor > 0) result = Math.max(result, safeFloor)

  return result
}

得到各项实际基数后,再乘对应费率得到养老、医疗、失业、公积金金额,并汇总 total。这一层输出会直接参与个税应纳税所得额计算。

3. 累计预扣税额计算

个税函数按"累计应纳税所得额"查税率区间并套公式:

javascript 复制代码
calculateTaxForIncome(cumulativeIncome, cumulativeDeduction, cumulativeSpecialDeductions = 0) {
  // 累计应纳税所得额
  const taxableIncome = cumulativeIncome - cumulativeDeduction - cumulativeSpecialDeductions
  if (taxableIncome <= 0) return 0

  for (const bracket of this.taxBrackets) {
    if (taxableIncome > bracket.min && taxableIncome <= bracket.max) {
      return Math.max(0, taxableIncome * bracket.rate - bracket.deduction)
    }
  }

  // 兜底走最高档
  const highestBracket = this.taxBrackets[this.taxBrackets.length - 1]
  return Math.max(0, taxableIncome * highestBracket.rate - highestBracket.deduction)
}

这里返回的是"截至当前月的累计应纳税额",不是当月税额。

4. 年度主流程:一次产出12个月明细

主流程会循环 12 次,每月做四件事:

  1. 计算当月五险一金
  2. 更新累计收入、累计专项扣除、累计附加扣除
  3. 计算累计应纳税额
  4. 反推当月税额并得到税后收入

核心公式是:

javascript 复制代码
// 当月应纳税额 = 累计应纳税额 - 上月累计已纳税额
const monthlyTax = Math.max(0, cumulativeTaxAmount - cumulativeTax)

// 税后收入 = 税前收入 - 五险一金 - 当月个税
const afterTaxIncome = monthlyIncome - insurance.total - monthlyTax

每月结果会记录为结构化对象(收入、扣除、税额、税后、累计值等),最终返回一个 12 项数组,界面层可直接用于表格展示和汇总统计。

5. 工具方法

核心逻辑外还有两个实用方法:

  • 金额格式化:把数字转成带千分位、保留两位小数的货币字符串
  • 城市基数读取:按城市键返回对应的社保/公积金上下限配置

这两个方法让计算层对外输出更稳定,页面调用时不需要重复写格式化和城市映射逻辑。

整套实现的重点是"规则集中、计算分层、月度与累计并行维护"。这样既能保证个税计算口径一致,也方便后续扩展更多收入场景。

相关推荐
小怪点点2 小时前
手写promise
前端·promise
国思RDIF框架2 小时前
RDIFramework.NET Web 敏捷开发框架 V6.3 发布 (.NET8+、Framework 双引擎)
前端
颜酱2 小时前
从0到1实现LFU缓存:思路拆解+代码落地
javascript·后端·算法
Mintopia2 小时前
如何在有限的时间里,活出几倍的人生
前端
炫饭第一名2 小时前
速通Canvas指北🦮——变形、渐变与阴影篇
前端·javascript·程序员
Neptune12 小时前
让我带你迅速吃透React组件通信:从入门到精通(上篇)
前端·javascript
小星哥哥2 小时前
JavaScript 动态导入 (Dynamic Imports)
javascript
阿懂在掘金2 小时前
Vue 表单避坑(一):为什么 v-model 绑定对象属性会偷偷修改父组件数据?
前端·vue.js
小码哥_常2 小时前
Android与JS交互:解锁混合开发的魔法之门
前端