JavaScript
的开发涉及创建用户界面和处理 Web
应用程序的表示层。以下是一些需要遵循的最佳实践以及示例,以确保干净且可维护的代码库:
将代码分解为更小的、可重用的模块。这增强了代码的可读性并使管理依赖关系变得更容易。
// users.js (module)
export function getUsers() {
// 获取数据
}
// main.js (entry point)
import { getUsers } from './users.js';
getUsers();
const
不会重新分配变量、let
只能在作用域内更改变量。
例子:
const PI = 3.14159;
let count = 0;
count = 10; // 有效
PI = 3; // 报错
尽量减少使用全局变量,以防止污染全局范围和潜在的冲突。
// 避免这样使用
let globalVar = 'global';
function someFunction() {
// ...
}
// 用这种方式使用
(function() {
let localVar = 'local';
function someFunction() {
// ...
}
})();
箭头函数提供简洁的语法并维护this
值,减少了对bind()
方法的使用。
// 常规写法
function add(a, b) {
return a + b;
}
// 箭头方法
const add = (a, b) => a + b;
将代码封装在模块或 IIFE
(立即调用函数表达式)中,以避免全局命名空间污染。
function myFunction() {
// ...
}
// 这样使用
(function() {
function myFunction() {
// ...
}
myFunction();
})();
用解构、扩展语法和模板文字等 ES6
写法来编写更简洁、更具表现力的代码。
// 解构
const { firstName, lastName } = user;
// 扩展
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combinedArray = [...arr1, ...arr2];
// 模板字符串
const name = `My name is ${firstName} ${lastName}.`;
将 HTML
和 JavaScript
代码分开。使用 CSS
类进行样式设置,并使用 JavaScript
而不是内联样式来操作类。
<button style="background-color: #007bff; color: #fff;">Click Mebutton>
<button class="primary-btn">Click Mebutton>
减少直接操作DOM
的方式,使用模板文字或有效更新 DOM
的库/框架。
const data = ['Item 1', 'Item 2', 'Item 3'];
function renderList(data) {
const list = document.getElementById('list');
list.innerHTML = '';
data.forEach(item => {
const listItem = document.createElement('li');
listItem.textContent = item;
list.appendChild(listItem);
});
}
renderList(data);
将事件侦听器附加到父元素,并利用事件委托来处理动态添加的元素上的事件。
<ul id="list">
ul>
<script>
document.getElementById('list').addEventListener('click', event => {
if (event.target.nodeName === 'LI') {
console.log(event.target.textContent);
}
});
script>
始终优雅地处理错误,以避免意外的应用程序崩溃并改善用户体验。
function divide(a, b) {
if (b === 0) {
throw new Error('不能为 0.');
}
return a / b;
}
try {
const result = divide(10, 0);
console.log(result);
} catch (error) {
console.error('报错:', error.message);
}
避免使用嵌套回调进行异步操作,并使用Promises
或Async/Await
来提高代码的可读性和可维护性。
使用promise
:
function fetchData() {
return fetch('https://api.example.com/data')
.then(response => response.json());
}
fetchData()
.then(data => console.log(data))
.catch(error => console.error('Error fetching data:', error));
使用Async/Await
:
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
} catch (error) {
throw new Error('Error fetching data:', error);
}
}
(async () => {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.error(error.message);
}
})();
在循环内执行 DOM
操作时,批量更改或使用 DocumentFragment
来最小化布局抖动并提高性能。
// 在循环中直接操作 DOM
const list = document.getElementById('list');
for (let i = 0; i < 1000; i++) {
const listItem = document.createElement('li');
listItem.textContent = `Item ${i}`;
list.appendChild(listItem);
}
// 用DocumentFragment方法批量更新dom
const list = document.getElementById('list');
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const listItem = document.createElement('li');
listItem.textContent = `Item ${i}`;
fragment.appendChild(listItem);
}
list.appendChild(fragment);
虽然三元运算符对于简洁的表达式很有用,但嵌套它们可能会导致代码难以阅读和理解。相反,对于复杂的条件,请使用常规的 if-else
语句。
// 嵌套三元运算符
const result = condition1
? value1
: condition2
? value2
: condition3
? value3
: defaultValue;
// 使用if-else
let result;
if (condition1) {
result = value1;
} else if (condition2) {
result = value2;
} else if (condition3) {
result = value3;
} else {
result = defaultValue;
}
当使用纯文本内容时,最好使用textContent
,防止innerHTML
潜在的安全漏洞(例如,跨站点脚本 - XSS
)
// 会被解析
const text = '';
const element = document.getElementById('myElement');
element.innerHTML = text;
// 纯文本展示
const text = '';
const element = document.getElementById('myElement');
element.textContent = text;
不要直接操作className
,而是使用add()
、remove()
、toggle()
和contains()
等classList
方法来管理 CSS
类。
<div id="myDiv" class="container">Contentdiv>
<script>
const element = document.getElementById('myDiv');
element.classList.add('highlight');
element.classList.remove('container');
if (element.classList.contains('highlight')) {
// ...
}
element.classList.toggle('active');
script>