JavaScript:两个世界——同一种语言
\n\n曾经,JavaScript 只是一种用于制作横幅动画和表单验证的语言。如今,它已成为 Web 开发人员最通用的工具。但这种通用性也带来了选择的复杂性:是用 Node.js 编写服务器逻辑,还是将 JS 保留给前端,而后端则交给 Python 或 Go?
\n\n在本文中,我们将直入主题。我们会采用真实场景,编写代码,并诚实地分析 JavaScript 在何处大放异彩,在何处最好寻找替代方案。如果您正面临技术栈的选择,或者只是想了解现代 Web 应用程序的“引擎盖下”发生了什么——那么您来对地方了。
\n\nJavaScript 在前端:浏览器之王
\n\n工作原理
\n使用 JavaScript 进行前端开发,涉及 DOM、事件、动画和浏览器 API 的操作。如今,这已不仅仅是“纯 JS”:React、Vue、Angular 和 Svelte 等生态系统已将界面创建转变为真正的工程学。
\n\n以下是一个简单示例,展示了 JS 如何让页面生动起来:
\n\n// 从服务器获取数据并将其显示在页面上\nasync function loadUsers() {\n try {\n const response = await fetch('https://api.example.com/users');\n const users = await response.json();\n \n const list = document.getElementById('user-list');\n users.forEach(user => {\n const item = document.createElement('li');\n item.textContent = `${user.name} — ${user.email}`;\n list.appendChild(item);\n });\n } catch (error) {\n console.error('加载错误:', error);\n }\n}\n\nloadUsers();\n\n一切都在用户的浏览器中运行。您提供 HTML 和脚本,其余工作由客户端完成。这带来了闪电般的界面响应:标签切换、动画、无需重新加载页面即可加载数据。
\n\nJavaScript 前端开发的优点
\n- \n
- 即时反馈 — 用户无需等待服务器响应即可立即看到更改。 \n
- 庞大的社区 — 任何问题都已解决,任何库都已编写。 \n
- 单一语言 — 如果您了解 JS,您就可以编写客户端和服务器端代码(全栈)。 \n
- 丰富的工具选择 — 从用于 SPA 的 React 到用于 SSR 的 Next.js。 \n
JavaScript 前端开发的缺点
\n- \n
- 客户端安全性 — 任何代码都可以在开发者工具中查看。不能在此处存储机密和密钥。 \n
- SEO 问题 — 纯 JS 渲染难以被搜索引擎索引(可通过 SSR 解决)。 \n
- 在弱设备上的性能 — 繁重的 SPA 可能在旧手机上运行缓慢。 \n
- 对浏览器的依赖 — 不同版本可能以不同方式解释代码。 \n
JavaScript 在后端:Node.js 及其生态系统
\n\n工作原理
\n当人们说“后端 JavaScript”时,指的是 Node.js——一个基于 V8 引擎构建的运行时环境。Node.js 允许在浏览器之外运行 JS:处理 HTTP 请求、与数据库、文件系统和网络套接字交互。
\n\n以下是一个典型的 Express.js 服务器:
\n\nconst express = require('express');\nconst app = express();\nconst PORT = 3000;\n\n// 用于解析 JSON 的中间件\napp.use(express.json());\n\n// 获取用户的路由\napp.get('/api/users', async (req, res) => {\n try {\n const users = await db.query('SELECT * FROM users');\n res.json(users);\n } catch (error) {\n res.status(500).json({ error: '服务器错误' });\n }\n});\n\n// 创建新用户的路由\napp.post('/api/users', async (req, res) => {\n const { name, email } = req.body;\n const newUser = await db.query(\n 'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',\n [name, email]\n );\n res.statu