基于ES5的Otto引擎无法使用部分字符串方法的解决方案咨询
解决Otto引擎(ECMA5)中
padStart()、getHours()等方法不支持的问题 首先先揪出你代码里的一个明显问题:你把date变量赋值成了时间戳的字符串(parseInt(...).toString(10)),之后虽然创建了result.DateAndTime = new Date(date),但后面调用date.getHours()时,其实是在给字符串调用Date对象的方法——这在任何JS环境里都会报错啊!应该改成result.DateAndTime.getHours()才对,不过假设这是笔误,咱们重点解决Otto这个ECMA5老引擎不支持ES6+方法的问题。
1. 自己实现padStart()替代方案
padStart()是ES2017才加入的特性,ECMA5环境肯定没有,咱们手动写一个兼容版就行,逻辑和原生方法完全一致:
function padStart(str, targetLength, padString) { str = String(str); targetLength = parseInt(targetLength, 10); padString = padString || ' '; if (str.length >= targetLength) { return str; } const paddingLength = targetLength - str.length; let padding = ''; while (padding.length < paddingLength) { padding += padString; } padding = padding.slice(0, paddingLength); return padding + str; }
用法和原生一样,比如你要把小时数转成两位格式,就用padStart(hours, 2, '0')。
2. 处理getHours()缺失的情况
虽然ECMA5标准里Date对象是包含getHours()的,但Otto作为嵌入式引擎,可能存在实现不全的情况。这时候咱们可以直接从时间戳计算小时,不用依赖Date对象的方法:
function getHoursFromTimestamp(timestamp) { // 把毫秒时间戳转成秒 const totalSeconds = Math.floor(timestamp / 1000); // 算出当天已经过了多少秒 const secondsInDay = totalSeconds % 86400; // 转成小时数 return Math.floor(secondsInDay / 3600); }
然后你的代码可以改成这样:
// 直接拿时间戳数字,别转字符串,避免ECMA5环境下的解析问题 const timestamp = parseInt(reverseString(hexPayload.substring(0,8)),16); result.DateAndTime = new Date(timestamp); // 兼容处理小时获取逻辑 let hours; if (typeof result.DateAndTime.getHours === 'function') { // 引擎支持原生方法就用原生的 hours = result.DateAndTime.getHours(); } else { // 不支持就用咱们自己实现的方法 hours = getHoursFromTimestamp(timestamp); } result.Volume1 = volume(reverseString(hexPayload.substring(18,26))) + 'meterCube' + hours;
另外提醒下,ECMA5的Date构造函数对字符串时间戳的解析不如现代浏览器宽松,所以直接传入数字型的时间戳会更可靠。
3. 再确认变量使用问题
一定要注意,你原来代码里的date是字符串类型,不是Date对象,所以调用date.getHours()肯定会抛出类型错误,这部分一定要改成从result.DateAndTime获取,或者用上面的时间戳计算方法。
这样调整后,代码应该就能在Otto引擎里正常运行了。
内容的提问来源于stack exchange,提问作者Hemanth
相关产品推荐
相关产品推荐

