JavaScript 反引号(` backtick)和双引号的不完全等价 ≠ 场景

一、backtick ````` 不能用作属性引号

js 复制代码
const wechat = {
  'my-name': 'JavaScript与编程艺术'
}
js 复制代码
const wechat = {
  `my-name`: 'JavaScript与编程艺术'
}

将报错:Uncaught SyntaxError: Unexpected template string

可以加[]解决:

js 复制代码
const wechat = {
  [`my-name`]: 'JavaScript与编程艺术'
}

二、反引号不能紧跟在表达式后

backtick ````` 如果紧跟值或表达式后面将报错。

下面引号不可替换成反引号:

js 复制代码
let start = 0 // 注意此处无分号
'backtick 和引号不等价的场景'.replace('backtick', '<backtick>')

若写成

js 复制代码
let start = 0 // 注意此处无分号
`backtick 和引号不等价的场景`.replace('backtick', '<backtick>')

则报错"Uncaught TypeError: 0 is not a function"

这个错误是因为 JavaScript 的自动分号插入 (ASI Automatic Semicolon Insertion)机制和模板字符串(反引号)的特性共同导致的。JavaScript 解析后相当于:

js 复制代码
let start = 0`backtick 和引号不等价的场景`.replace('backtick', '<backtick>')

报错原因是 template string 无需括号即可被当做函数参数调用。

只要模板字符串紧跟在某个表达式后面(没有分号),这个表达式就会被当作 tag 函数来调用模板字符串 template literals,这叫做 tagged template:

js 复制代码
// 这些都会被当作函数调用
fn`hello`        // ✅ fn 是函数
obj.fn`hello`    // ✅ fn 是函数
(() => {})`hello` // ✅ 箭头函数被调用
0`hello`         // ❌ 0 不是函数
null`hello`      // ❌ null 不是函数

const date = new Date()
`backtick 和引号不等价的场景`.replace('backtick', '<backtick>')
// ❌ VM902:2 Uncaught TypeError: (intermediate value) is not a function

三、静态 import 模块名不能使用反引号包裹

实验代码 back-tick/import.js:

js 复制代码
// ❌ SyntaxError: Unexpected template string
import { test } from `node:test`
ts 复制代码
❯ node back-tick/import.js
file:///F:/temp/back-tick/import.js:1
import { test } from `node:test`
                     ^^^^^^^^^^^

SyntaxError: Unexpected template string
    at compileSourceTextModule (node:internal/modules/esm/utils:346:16)
    at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:107:18)
    at #translate (node:internal/modules/esm/loader:536:12)
    at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:583:27)
    at async ModuleJob._link (node:internal/modules/esm/module_job:162:19)

Node.js v22.18.0

静态导入模块不能使用反引号包裹。当然动态是可以的:

js 复制代码
const { test } = await import(`node:test`)
console.log(test)

能正常输出且输出和 import { test } from 'node:test' 一样。dynamic import 经常用在对启动性能有极致追求的场景,比如 OpenCode 或 Claude Code 等 CLI 中。

相关推荐
谢亮_vipxieliang2 小时前
深入理解 JavaScript 数据类型与类型转换
开发语言·javascript·ecmascript
程序员Sunday11 小时前
JavaScript 事件循环面试题,宏任务与微任务怎么执行|Sunday面试指南
开发语言·javascript·面试·校招·事件循环·程序员sunday
默_笙13 小时前
🌊 向量库和 ES 都查不出"关系",我只好给奶茶建了一张人脉网
前端·javascript
思无邪6613 小时前
用 AI 做 JS 逆向:从抓包到复现的完整方法论
开发语言·javascript·人工智能
福兮说15 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic
可乐鸡翅yeah_16 小时前
video.js 集成 hls.js 开发 M3U8 播放器,新手高频踩坑
开发语言·前端·javascript·后端·ecmascript·m3u8·音视频在线播放
用户1179536547817 小时前
TRAE vs Claude Code 性能对比:从代码生成、多文件重构到底层吞吐,谁更适合你的日常开发?
javascript
kill52218 小时前
useRef
前端·javascript·react.js
米多科技19 小时前
我做了一个 3D 虚拟世界基底,在上面再搭 3D 世界或元宇宙,事半功倍
javascript·人工智能·github