自定义组件命名为Date时,如何访问JS内置Date对象?
问题:自定义Date组件与JS内置Date对象冲突的解决方法
我正在学习NextJS教程并做了自定义修改。教程中的Date组件未使用JS内置Date对象,因此无命名冲突;但我在将自定义组件命名为Date的同时,需要在同一文件中调用JS内置Date对象,此时执行new Date()会触发自定义组件函数并抛出错误。
我知道可通过重命名组件解决问题,但出于学习需求,想了解是否有合法方式复用内置对象名称并避免冲突,以深入理解JS/React/NextJS内部原理。
代码示例(date.js)
import { format, parse } from "date-fns" export default function Date({ dateString }) { const date = parse(dateString, "LLLL d, yyyy", new Date()) // 这里想调用内置Date() return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time> }
抛出的错误
import { format, parse } from "date-fns" 2 | > 3 | export default function Date({ dateString }) { | ^ 4 | const date = parse(dateString, "LLLL d, yyyy", new Date()) 5 | return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time> 6 | } node_modules/next/dist/server/dev/next-dev-server.js:762 error - components/date.js (3:31) @ new Date node_modules/next/dist/build/output/log.js:33 [31merror[39m - TypeError: Cannot destructure property 'dateString' of 'undefined' as it is undefined. at new Date (/Users/cfork/projects/nextjs-blog/components/date.js:3:32) at Date (/Users/cfork/projects/nextjs-blog/components/date.js:4:50)
解决方法
方法1:直接访问全局作用域的Date对象
ES模块有独立作用域,自定义的Date会覆盖模块内部对Date的引用,但全局内置Date可通过globalThis(浏览器/Node.js通用)访问:
import { format, parse } from "date-fns" export default function Date({ dateString }) { const date = parse(dateString, "LLLL d, yyyy", new globalThis.Date()) return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time> }
方法2:提前保存内置Date的引用
在定义自定义组件前,先把全局Date对象存到变量中,后续用这个变量调用内置对象:
import { format, parse } from "date-fns" // 提前保存内置Date的引用 const NativeDate = Date; export default function Date({ dateString }) { const date = parse(dateString, "LLLL d, yyyy", new NativeDate()) return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time> }
原理说明
ES模块内的函数声明会提升,当你定义function Date(...)后,模块内所有后续的Date引用都会指向这个自定义组件,而非全局内置对象。通过全局作用域访问或提前保存引用,就能绕开模块内的覆盖逻辑,正常调用内置Date。
内容的提问来源于stack exchange,提问作者CloudyBytes
相关产品推荐
相关产品推荐

