JSX:看似 HTML 的 “卧底”?

面试时被问到 JSX,很多人会说:"就是在 JavaScript 里写 HTML 嘛!" 但如果面试官追问:"JSX 能直接在浏览器里运行吗?""它和 HTML 到底有啥区别?" 不少人就卡壳了。其实 JSX 这东西,表面上像 HTML,骨子里却是个 "披着 HTML 外衣的 JavaScript 卧底"。

一、JSX 是啥?------ 不是 HTML,是 "语法糖"

先看个例子,这是一段典型的 JSX 代码:

jsx 复制代码
const element = <h1 className="title">Hello, JSX!</h1>;

看起来是不是和 HTML 一模一样?但它有个隐藏身份:JavaScript 的扩展语法(可以理解为 "语法糖")。它的全称是 "JavaScript XML",意思是 "在 JavaScript 里写 XML(HTML 是 XML 的一种)"。

React 之所以搞出 JSX,是为了解决一个痛点:让 UI 结构和 JavaScript 逻辑能更自然地结合。在没有 JSX 的年代,我们得用纯 JavaScript 写 UI,比如这样:

javascript 复制代码
// 没有JSX的日子,用纯JS创建UI(像写配置文件)
const element = React.createElement(
  'h1',
  { className: 'title' },
  'Hello, 纯JS!'
);

对比一下,JSX 的写法是不是直观多了?就像直接在代码里画 UI 一样,这也是 React 的一大特色。

二、JSX 能直接运行吗?------ 不能!得靠 "翻译官"

浏览器只能理解纯 JavaScript 代码,根本不认识 JSX。那我们写的 JSX 是怎么跑起来的?

答案是:需要被编译成纯 JavaScript 代码 。这个 "翻译官" 通常是 Babel(React 项目默认集成),它会把 JSX 转换成 React 提供的一个函数调用 ------React.createElement

比如前面的 JSX 代码:

jsx 复制代码
const element = <h1 className="title">Hello, JSX!</h1>;

会被 Babel 翻译成:

javascript 复制代码
const element = React.createElement(
  'h1', // 标签名(或组件)
  { className: 'title' }, // 标签属性(注意是className,不是class)
  'Hello, JSX!' // 子元素(文本或其他节点)
);

这就是 JSX 的底层原理:它只是React.createElement函数的语法糖,最终都会变成纯 JavaScript 代码。

三、React.createElement是啥?------ 虚拟 DOM 的 "设计师"

React.createElement函数的作用,是创建一个描述 DOM 结构的 JavaScript 对象 (也就是 "虚拟 DOM")。我们可以打印一下上面的element

javascript 复制代码
console.log(element);
// 输出结果(简化版):
{
  type: 'h1',
  props: {
    className: 'title',
    children: 'Hello, JSX!'
  },
  // ...其他属性(如key、ref等)
}

这个对象记录了:

  • type:标签类型(如'h1''div',或 React 组件);
  • props:标签的属性(如classNameid)和子元素(children);

React 会根据这个 "虚拟 DOM 对象",去创建或更新真实的 DOM 节点。这也是 React 性能高效的原因之一 ------ 通过对比新旧虚拟 DOM 的差异(Diff 算法),只更新变化的部分,避免全量重绘。

四、实战对比:JSX vs React.createElement

看一个更复杂的例子,用 JSX 写一个列表:

jsx 复制代码
// JSX写法
<ul>
  {todos.map(todo => (
    <li key={todo.id}>{todo.title}</li>
  ))}
</ul>

如果用React.createElement写,是这样的:

javascript 复制代码
// 等价的createElement写法
React.createElement(
  'ul',
  null,
  todos.map(todo => 
    React.createElement(
      'li',
      { key: todo.id },
      todo.title
    )
  )
);

是不是瞬间觉得 JSX 香多了?尤其是复杂 UI,JSX 能让代码可读性提升一个档次。这也是为什么 React 官方推荐用 JSX------ 它让开发者把精力放在 "写什么",而不是 "怎么实现"。

五、JSX 语法规则

JSX 虽然长得像 HTML,但有一些语法差异,这些差异是面试高频考点:

(1)className 代替 class

在 HTML 里给元素加类名用class,但 JSX 里必须用className------ 因为class是 JavaScript 的关键字(用于定义类),为了避免冲突,JSX 改用className

jsx 复制代码
// 正确:用className
<div className="container">内容</div>

// 错误:不能用class
<div class="container">内容</div> // 会被忽略或警告

(2)htmlFor 代替 for

同理,HTML 里的for属性(用于关联 label 和 input)在 JSX 里要用htmlFor,因为for也是 JavaScript 关键字。

jsx 复制代码
// 正确:用htmlFor
<label htmlFor="username">用户名:</label>
<input id="username" />

// 错误:不能用for
<label for="username">用户名:</label>

(3)必须有唯一根元素

JSX 要求 "最外层必须有一个唯一的父元素",否则会报错。如果不想多一个多余的 div,可以用 Fragment(<></>)当根元素(前面讲过)。

jsx 复制代码
// 正确:用Fragment当根元素
<>
  <h1>标题</h1>
  <p>内容</p>
</>

// 错误:没有唯一根元素
<h1>标题</h1>
<p>内容</p> // 报错:Adjacent JSX elements must be wrapped in an enclosing tag

(4)嵌入 JavaScript 表达式用{}

JSX 里可以用{}嵌入任何 JavaScript 表达式(变量、函数调用、三元运算等),但不能嵌入语句(如iffor)。

jsx 复制代码
const name = 'React';
const isLoggedIn = true;

// 正确:嵌入变量、三元表达式
<div>
  <p>Hello, {name}</p>
  {isLoggedIn ? <p>已登录</p> : <p>未登录</p>}
</div>

// 错误:不能嵌入语句
<div>
  {if (isLoggedIn) { <p>已登录</p> }} // 报错:Unexpected token
</div>

(5)事件绑定用驼峰命名

HTML 里事件名是全小写(如onclick),JSX 里要用驼峰命名(如onClick)。

jsx 复制代码
// 正确:驼峰命名onClick
<button onClick={() => console.log('点击了')}>点击我</button>

// 错误:全小写onclick
<button onclick={() => console.log('点击了')}>点击我</button> // 不生效

六、总结:JSX 的核心考点与底层原理

  1. 定义:JSX 是 JavaScript 扩展语法,允许在 JS 中嵌入 HTML 结构,提升 UI 代码的可读性。
  2. 本质 :语法糖,编译后会变成React.createElement调用,生成虚拟 DOM 对象。
  3. 关键语法classNamehtmlFor、驼峰事件名、{}嵌入表达式、唯一根元素。
  4. 渲染流程 :JSX → 编译为createElement → 生成虚拟 DOM → ReactDOM.render → 真实 DOM。
相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax