在 JavaScript 中,%是取余运算符(也叫模运算符)。

29 阅读3分钟

基本用法

// 10 % 2 表示 10 除以 2 的余数
console.log(10 % 2);  // 0
// 解释:10 ÷ 2 = 5 余 0

console.log(10 % 3);  // 1
// 解释:10 ÷ 3 = 3 余 1

console.log(10 % 4);  // 2
// 解释:10 ÷ 4 = 2 余 2

详细解释

a % b返回 a除以 b余数

// 公式:a % b = a - b * Math.floor(a / b)
console.log(10 % 3);  // 1
// 计算:10 - 3 * Math.floor(10/3) = 10 - 3 * 3 = 1

常见应用场景

1. 判断奇偶性

function isEven(num) {
  return num % 2 === 0;  // 能被2整除就是偶数
}

console.log(isEven(10));  // true
console.log(isEven(7));   // false
console.log(isEven(0));   // true

2. 循环数组索引

const colors = ['red', 'green', 'blue', 'yellow'];
let index = 0;

// 循环获取颜色
function getNextColor() {
  const color = colors[index % colors.length];
  index++;
  return color;
}

console.log(getNextColor());  // red
console.log(getNextColor());  // green
console.log(getNextColor());  // blue
console.log(getNextColor());  // yellow
console.log(getNextColor());  // red (回到第一个)

3. 格式化时间

// 秒数转分钟和秒
function formatTime(seconds) {
  const minutes = Math.floor(seconds / 60);
  const remainingSeconds = seconds % 60;
  return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
}

console.log(formatTime(125));  // "2:05"
console.log(formatTime(360));  // "6:00"

4. 判断是否能被整除

function isDivisibleBy(num, divisor) {
  return num % divisor === 0;
}

console.log(isDivisibleBy(10, 2));  // true
console.log(isDivisibleBy(10, 3));  // false
console.log(isDivisibleBy(15, 5));  // true

5. 生成循环序列

// 生成 0-2 的循环序列
for (let i = 0; i < 10; i++) {
  console.log(i % 3);  // 0,1,2,0,1,2,0,1,2,0
}

特殊值和边界情况

// 正数
console.log(5 % 3);    // 2
console.log(5 % 5);    // 0
console.log(5 % 6);    // 5 (被除数小于除数时返回被除数本身)
console.log(5 % 1);    // 0

// 负数
console.log(-5 % 3);   // -2
console.log(5 % -3);   // 2
console.log(-5 % -3);  // -2

// 零
console.log(0 % 5);    // 0
console.log(5 % 0);    // NaN (不能除以0)

// 小数
console.log(5.5 % 2);  // 1.5
console.log(5 % 2.5);  // 0

与取整运算符的区别

// 取余 vs 取整
console.log(10 % 3);   // 1 (余数)
console.log(Math.floor(10 / 3));  // 3 (商的整数部分)
console.log(10 / 3);   // 3.333... (商)

// 计算商和余数
function divmod(dividend, divisor) {
  const quotient = Math.floor(dividend / divisor);
  const remainder = dividend % divisor;
  return [quotient, remainder];
}

console.log(divmod(10, 3));  // [3, 1]
console.log(divmod(17, 5));  // [3, 2]

实际应用示例

1. 分页计算

// 计算总页数
function getTotalPages(totalItems, itemsPerPage) {
  return Math.ceil(totalItems / itemsPerPage);
}

// 计算当前页的起始索引
function getPageStartIndex(currentPage, itemsPerPage) {
  return (currentPage - 1) * itemsPerPage;
}

// 计算最后一页的项目数
function getLastPageItems(totalItems, itemsPerPage) {
  const remainder = totalItems % itemsPerPage;
  return remainder === 0 ? itemsPerPage : remainder;
}

console.log(getTotalPages(25, 10));      // 3
console.log(getPageStartIndex(3, 10));   // 20
console.log(getLastPageItems(25, 10));   // 5

2. 颜色循环

const colors = ['#ff0000', '#00ff00', '#0000ff'];

function getColorByIndex(index) {
  return colors[index % colors.length];
}

// 生成颜色序列
for (let i = 0; i < 8; i++) {
  console.log(`颜色${i}: ${getColorByIndex(i)}`);
}

3. 验证身份证校验码

// 身份证最后一位校验码计算
function calculateIDCheckCode(id) {
  const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
  
  let sum = 0;
  for (let i = 0; i < 17; i++) {
    sum += parseInt(id[i]) * weights[i];
  }
  
  const remainder = sum % 11;
  return checkCodes[remainder];
}

// 示例
console.log(calculateIDCheckCode('110101199003076'));  // 需要计算

性能考虑

// 性能对比
console.time('取余运算');
for (let i = 0; i < 1000000; i++) {
  const result = i % 100;
}
console.timeEnd('取余运算');  // 约 2-5ms

// 位运算替代(仅适用于2的幂次方)
console.time('位运算');
for (let i = 0; i < 1000000; i++) {
  const result = i & 63;  // 等价于 i % 64
}
console.timeEnd('位运算');  // 约 1-3ms

总结

%是 JavaScript 中的取余运算符,用于计算两个数相除后的余数。它在编程中有广泛的应用:

  1. 数学计算:求余数
  2. 逻辑判断:判断奇偶、是否能被整除
  3. 循环控制:数组循环、颜色循环
  4. 格式化:时间格式化、分页计算
  5. 算法实现:哈希函数、校验码计算

记住关键点:

  • a % b返回 a除以 b的余数
  • 结果为 0 表示能被整除
  • 被除数小于除数时,返回被除数本身
  • 除数为 0 时返回 NaN
  • 可用于正数、负数和浮点数