让你的代码更简洁、更强大、更专业!
上一篇文章中,我们介绍了 ES6+ 的一些基础特性,帮助你告别"上古时代"的 JavaScript 写法。今天,我们将继续前行,探索更多高级特性,让你的代码功力更上一层楼!
准备好大开眼界了吗?那就开始吧!
1. 模板字符串:字符串拼接不再是痛点
javascript
// 旧世界:字符串拼接的烦恼
const name = "张三";
const age = 28;
const greeting = "你好,我是" + name + ",今年" + age + "岁。";
// 新世界:模板字符串优雅搞定
const greeting = `你好,我是${name},今年${age}岁。`;
// 多行字符串不再需要 \n
const html = `
<div>
<h1>用户信息</h1>
<p>姓名:${name}</p>
<p>年龄:${age}</p>
</div>
`;
标签模板:更进一步的强大功能
javascript
// 自定义标签函数处理模板字符串
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
const value = values[i] || "";
return (
result +
str +
(typeof value === "number" ? `<strong>${value}</strong>` : value)
);
}, "");
}
const name = "张三";
const age = 28;
const html = highlight`我是${name},今年${age}岁。`;
// 结果:我是张三,今年<strong>28</strong>岁。
实战应用:使用 styled-components 创建样式化组件:
javascript
const Button = styled.button`
background-color: ${(props) => (props.primary ? "blue" : "white")};
color: ${(props) => (props.primary ? "white" : "blue")};
padding: 10px 15px;
border-radius: 4px;
&:hover {
opacity: 0.8;
}
`;
2. 类与继承:面向对象编程更简洁
javascript
// 旧世界:原型继承
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function () {
console.log(`你好,我是${this.name}`);
};
function Employee(name, age, company) {
Person.call(this, name, age);
this.company = company;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
// 新世界:ES6 类继承
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`你好,我是${this.name}`);
}
}
class Employee extends Person {
constructor(name, age, company) {
super(name, age);
this.company = company;
}
work() {
console.log(`${this.name}在${this.company}工作`);
}
}
const employee = new Employee("张三", 28, "科技公司");
employee.sayHello(); // 你好,我是张三
employee.work(); // 张三在科技公司工作
私有属性与方法:JavaScript 类进化
javascript
class BankAccount {
// 私有属性
#balance = 0;
constructor(owner) {
this.owner = owner;
}
// 私有方法
#validateAmount(amount) {
return amount > 0 && Number.isFinite(amount);
}
deposit(amount) {
if (this.#validateAmount(amount)) {
this.#balance += amount;
return true;
}
return false;
}
getBalance() {
return this.#balance;
}
}
const account = new BankAccount("张三");
account.deposit(100);
console.log(account.getBalance()); // 100
// console.log(account.#balance); // 语法错误:私有属性无法直接访问
3. 模块化与动态导入:按需加载不再是梦
javascript
// 导出模块
// math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
export default class Calculator {
// 类实现...
}
// 导入模块
// app.js
import Calculator, { add, subtract } from "./math.js";
// 或者导入所有
import Calculator, * as MathUtils from "./math.js";
// 动态导入:按需加载模块
button.addEventListener("click", async () => {
try {
const { default: Chart } = await import("./chart.js");
const chart = new Chart();
chart.render("#container");
} catch (error) {
console.error("加载图表模块失败", error);
}
});
实战应用:React 中的代码分割
javascript
// React Router 中的懒加载路由
import { lazy, Suspense } from "react";
import { Routes, Route } from "react-router-dom";
const Home = lazy(() => import("./pages/Home"));
const Dashboard = lazy(() => import("./pages/Dashboard"));
const Settings = lazy(() => import("./pages/Settings"));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}
4. 可选链操作符与空值合并:告别层层判断
javascript
// 旧世界:深层属性访问的安全检查
function getUserCity(user) {
if (user && user.address && user.address.city) {
return user.address.city;
}
return "未知城市";
}
// 新世界:可选链操作符简化代码
function getUserCity(user) {
return user?.address?.city || "未知城市";
}
// 空值合并操作符:避免将 '' 和 0 视为假值
const count = data?.count ?? 0; // 只有当 data.count 为 null 或 undefined 时才使用默认值
const username = user?.name ?? "游客"; // 空字符串会被保留,不会使用默认值
实战应用:React 组件中处理可能不存在的属性
javascript
function UserProfile({ user }) {
return (
<div>
<h2>{user?.name ?? "匿名用户"}</h2>
<p>邮箱: {user?.email ?? "未提供"}</p>
<p>城市: {user?.address?.city ?? "未知"}</p>
<p>积分: {user?.stats?.points ?? 0}</p>
</div>
);
}
5. 现代数组方法:让数据处理更优雅
javascript
const users = [
{ id: 1, name: "张三", age: 28, active: true },
{ id: 2, name: "李四", age: 32, active: false },
{ id: 3, name: "王五", age: 24, active: true },
];
// find:查找符合条件的第一个元素
const user = users.find((user) => user.id === 2);
// some 和 every:检查数组元素
const hasActiveUsers = users.some((user) => user.active);
const allYoung = users.every((user) => user.age < 35);
// flatMap:扁平化映射结果
const userPosts = users.flatMap((user) => user.posts || []);
// at:支持负索引的数组访问
const lastUser = users.at(-1); // 等同于 users[users.length - 1]
// 新的数组方法组合使用
const activeUserNames = users
.filter((user) => user.active)
.map((user) => user.name);
实战应用:React 中的数据转换
javascript
function UserList({ users }) {
// 对用户数据进行排序和过滤
const activeUsers = useMemo(() => {
return (
users
?.filter((user) => user.active)
.sort((a, b) => a.name.localeCompare(b.name)) || []
);
}, [users]);
return (
<ul>
{activeUsers.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
学习路径:接下来去哪里?
恭喜你!完成本篇学习后,你的 JavaScript 技能已经迈向现代化。下一步,我们将深入探索前端框架的精髓:
在下一篇《React 核心原理与 Hooks 最佳实践》中,我们将探讨:
- React 组件设计模式
- 自定义 Hooks 开发技巧
- 状态管理策略对比
- 性能优化实战指南
不要错过!继续关注我们的前端开发系列,成为真正的前端高手!
关于作者
Hi,我是 hyy,一位热爱技术的全栈开发者:
- 🚀 专注 TypeScript 全栈开发,偏前端技术栈
- 💼 多元工作背景(跨国企业、技术外包、创业公司)
- 📝 掘金活跃技术作者
- 🎵 电子音乐爱好者
- 🎮 游戏玩家
- 💻 技术分享达人
加入我们
欢迎加入前端技术交流圈,与 10000+开发者一起:
- 探讨前端最新技术趋势
- 解决开发难题
- 分享职场经验
- 获取优质学习资源
添加方式:掘金摸鱼沸点 👈 扫码进群