You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何JS热量计算函数在iOS端返回NaN,桌面端却正常运行?

问题分析与解决方案

核心问题:iOS输入法智能引号导致高度解析失败

iOS默认输入法会自动将输入的单引号转换成弯引号(’),但你的ftTocm函数仅用split("'")(直引号)分割字符串,导致分割后ft[1]为整个原输入内容,parseInt转换后得到NaN,最终引发后续所有计算结果为NaN。

其他潜在触发NaN的问题

  • 无输入合法性校验:若用户输入空值、非数字内容,parseInt/parseFloat会返回NaN,直接带入计算会导致异常。
  • 变量重复声明:lbsToProtein中已声明calorieIntake和proteinGrams,后续又用var重复声明,属于不良编码习惯。
  • switch无默认分支:若weightGoal不是1/2/3,calorieIntake和proteinGrams会保持undefined,计算后得到NaN。

修复步骤

1. 兼容智能引号的高度解析

修改ftTocm函数,同时处理直引号和弯引号,并增加格式校验:

function ftTocm(height) {
  console.log(height)
  // 统一替换直/弯引号后分割
  var ft = height.replace(/['’]/g, "'").split("'");
  // 校验分割后格式是否合法
  if (ft.length < 2) return NaN;
  
  var feet = parseInt(ft[0]);
  var inches = parseInt(ft[1]);
  // 校验数字转换是否成功
  if (isNaN(feet) || isNaN(inches)) return NaN;
  
  var cm = (feet * 12 + inches) * 2.54;
  console.log("cm", cm);
  return cm;
}

2. 增加输入合法性校验

在submit函数中提前校验所有输入,无效时提示用户:

function submit() {
  var lbs = parseFloat(document.getElementById('lbs-input').value);
  var age = parseInt(document.getElementById('age-input').value);
  var height = document.getElementById('height-input').value;
  var goal_input = document.getElementById('select');
  var excercise_input = document.getElementById('excercise');
  var excercise = parseInt(excercise_input.value);
  var weightGoal = parseInt(goal_input.value);

  // 基础输入校验
  if (isNaN(lbs) || lbs <= 0 || isNaN(age) || age <= 0 || !height) {
    alert("请输入有效的体重、年龄和身高");
    return;
  }

  var cm = ftTocm(height);
  if (isNaN(cm)) {
    alert("请输入正确格式的身高,例如:5'10");
    return;
  }

  if (isNaN(weightGoal) || ![1,2,3].includes(weightGoal)) {
    alert("请选择有效的体重目标");
    return;
  }

  if (isNaN(excercise) || excercise < 1 || excercise >3) {
    alert("请选择有效的运动强度");
    return;
  }

  var info = lbsToProtein(lbs, weightGoal, cm, age, excercise);
  document.getElementById('calories').innerHTML = info[1] + ' calories';
  document.getElementById('protein').innerHTML = info[0] + ' grams';
  document.getElementById('form').style.cssText = 'display: none;';
  document.getElementById('results').style.cssText = 'display: block !important;';
}

3. 修复lbsToProtein的潜在问题

移除重复变量声明,增加默认分支处理异常情况:

function lbsToProtein(lbs, weightGoal, cm, age, excercise) {
  var kgs = lbs / 2.205;
  var calorieIntake;
  var proteinGrams;
  switch (weightGoal) {
    case 1: //维持体重
      calorieIntake = (kgs * 13.397) + (cm * 4.799) - (age * 5.677) + 88.362 + excercise;
      proteinGrams = kgs * 0.8;
      break;
    case 2: //增重
      calorieIntake = ((kgs * 13.397) + (cm * 4.799) - (age * 5.677) + 88.362) + 700 + excercise;
      proteinGrams = kgs * 1.35;
      break;
    case 3: //减重
      calorieIntake = (((kgs * 13.397) + (cm * 4.799) - (age * 5.677) + 88.362) - 700) + excercise;
      proteinGrams = kgs * 0.8;
      break;
    default:
      // 处理异常目标值
      calorieIntake = NaN;
      proteinGrams = NaN;
      break;
  }
  // 移除重复的var声明
  calorieIntake = Math.round(calorieIntake);
  proteinGrams = Math.round(proteinGrams);
    
  console.log("Protein: "+proteinGrams+"g");
  console.log('Calorie Intake: '+calorieIntake+'cal', (typeof calorieIntake));
  var info = [proteinGrams, calorieIntake];
  console.log(info)
  return info;
}

测试建议

  • 在iOS设备上用默认输入法输入5'10格式的身高,验证解析是否正常
  • 测试空输入、非法格式输入,确认能弹出提示而非返回NaN

内容的提问来源于stack exchange,提问作者RaidLucky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 23:51:18