包装Intl.DateTimeFormat的format方法时遇RangeError错误求助
解决Intl.DateTimeFormat自定义format方法时的RangeError问题
你遇到的这个问题,核心原因是函数上下文丢失了。当你把dtf.format赋值给变量format时,这个函数原本绑定的this(也就是dtf实例)被弄丢了——直接调用format(date)时,this指向的是全局对象(严格模式下是undefined),这就导致Intl内部处理时无法正确识别时间值,抛出了RangeError: Invalid time value。
下面给你几个可行的解决方案:
方案1:用bind绑定原实例上下文
修改你保存原format方法的代码,给它绑定原dtf实例的上下文,这样调用时this就不会跑偏了:
var str = '2018-05-30T12:20:51.526Z' var date = new Date(str) var dtf = new Intl.DateTimeFormat('en'); // 用bind绑定原dtf实例的上下文 var format = dtf.format.bind(dtf); dtf.format = function(str) { var date = new Date(str); return format(date); } console.log(new Intl.DateTimeFormat('en').format(date)) // 5/30/2018 console.log(dtf.format(str)) // 现在会正常输出5/30/2018
方案2:直接在新方法里用call/apply指定上下文
不需要单独保存原format方法,直接在自定义方法里调用原实例的format时,用call或apply把this指定为原dtf实例:
var str = '2018-05-30T12:20:51.526Z' var date = new Date(str) var dtf = new Intl.DateTimeFormat('en'); dtf.format = function(str) { var date = new Date(str); // 用call指定this为原dtf实例 return Intl.DateTimeFormat.prototype.format.call(this, date); } console.log(new Intl.DateTimeFormat('en').format(date)) // 5/30/2018 console.log(dtf.format(str)) // 正常输出5/30/2018
方案3:封装新函数而非修改原实例方法(更推荐)
修改内置对象实例的方法不是最佳实践,更安全的方式是封装一个独立的函数,专门处理字符串转Date再格式化的逻辑:
var str = '2018-05-30T12:20:51.526Z' var date = new Date(str) var dtf = new Intl.DateTimeFormat('en'); // 封装自定义格式化函数 function formatDateString(dateStr) { const dateObj = new Date(dateStr); // 可以加个校验,避免无效日期 if (isNaN(dateObj.getTime())) { throw new Error('Invalid date string'); } return dtf.format(dateObj); } console.log(new Intl.DateTimeFormat('en').format(date)) // 5/30/2018 console.log(formatDateString(str)) // 正常输出5/30/2018
这样既避免了修改内置方法可能带来的潜在问题,还能额外增加日期有效性校验,让代码更健壮。
内容的提问来源于stack exchange,提问作者user3568719
相关产品推荐
相关产品推荐

