JavaScript 语句
定义
语句(Statement)是JavaScript代码的基本执行单元,用于执行特定的操作或控制程序流程。
分号使用规则
自动分号插入(ASI)
// JavaScript引擎会自动插入分号
let a = 1
let b = 2
console.log(a + b) // 引擎自动在行尾插入分号
推荐显式使用分号
// 明确的分号使用(推荐)
let sum = a + b;
let diff = a - b;
console.log(sum);
ASI的陷阱
// 危险情况1:return语句
function getValue() {
return
{ name: "John" }; // 不会返回对象!
}
console.log(getValue()); // undefined
// 正确写法
function getValue() {
return {
name: "John"
};
}
// 危险情况2:数组访问
let arr = [1, 2, 3]
[0, 1].forEach(i => console.log(arr[i])); // TypeError
// 正确写法
let arr = [1, 2, 3];
[0, 1].forEach(i => console.log(arr[i]));
语句类型
1. 表达式语句
// 表达式作为语句
42; // 数字表达式
"hello"; // 字符串表达式
myFunction(); // 函数调用表达式
a = b + c; // 赋值表达式
2. 声明语句
// 变量声明
var oldVar;
let modernVar;
const CONSTANT = 10;
// 函数声明
function myFunction() {
return "hello";
}
// 类声明
class MyClass {
constructor() {}
}
3. 控制流语句
// 条件语句
if (condition) {
// 代码块
}
// 循环语句
for (let i = 0; i < 10; i++) {
console.log(i);
}
// 跳转语句
break;
continue;
return value;
代码块和作用域
块语句
// 使用花括号创建代码块
{
let blockScoped = "只在块内可见";
console.log(blockScoped);
}
// console.log(blockScoped); // ReferenceError
// 条件代码块
if (true) {
let localVar = "条件块内";
console.log(localVar);
}
作用域示例
// 函数作用域(var)
function testVar() {
if (true) {
var funcScoped = "函数作用域";
}
console.log(funcScoped); // 可以访问
}
// 块作用域(let/const)
function testLet() {
if (true) {
let blockScoped = "块作用域";
}
// console.log(blockScoped); // ReferenceError
}
标签语句
基本语法
// 标签语句语法
label: statement
// 示例
outerLoop: for (let i = 0; i < 3; i++) {
innerLoop: for (let j = 0; j < 3; j++) {
if (i === 1 && j === 1) {
break outerLoop; // 跳出外层循环
}
console.log(`i: ${i}, j: ${j}`);
}
}
实际应用
// 复杂循环控制
parseData: {
if (!data) {
console.log("无数据");
break parseData;
}
if (!data.valid) {
console.log("数据无效");
break parseData;
}
// 处理数据
processData(data);
}
// 使用标签的continue
outerLoop: for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
if (j === 2) {
continue outerLoop; // 跳到外层循环的下一次迭代
}
console.log(`${i},${j}`);
}
}
空语句
语法和用途
// 空语句(只有分号)
;
// 在循环中的应用
for (let i = 0; i < arr.length; arr[i++] = 0); // 循环体为空语句
// 更清晰的写法
for (let i = 0; i < arr.length; i++) {
arr[i] = 0; // 显式的循环体
}
语句与表达式的区别
语句不能作为值
// 这些是语句,不能作为值使用
// let x = if (true) { 42 }; // SyntaxError
// let y = for (;;) { break; }; // SyntaxError
// 表达式可以作为值
let x = true ? 42 : 0; // 条件表达式
let y = (function() { return 42; })(); // 函数表达式
立即执行函数表达式(IIFE)
// 将语句包装成表达式
(function() {
// 语句代码
let localVar = "局部变量";
console.log(localVar);
})();
// 箭头函数版本
(() => {
let localVar = "局部变量";
console.log(localVar);
})();
最佳实践
1. 分号使用建议
// 推荐:始终使用分号
let result = calculate();
return result;
// 避免:依赖自动插入
let result = calculate()
return result
2. 代码块组织
// 清晰的代码块结构
function processUser(user) {
// 输入验证块
{
if (!user) throw new Error("User required");
if (!user.id) throw new Error("User ID required");
}
// 数据处理块
{
user.name = user.name.trim();
user.email = user.email.toLowerCase();
}
// 返回结果
return user;
}
3. 避免复杂的标签语句
// 不推荐:过于复杂的标签使用
complicated: {
nested: {
if (condition1) break complicated;
if (condition2) break nested;
// 复杂逻辑
}
}
// 推荐:使用函数重构
function handleComplexLogic() {
if (condition1) return "result1";
if (condition2) return "result2";
// 清晰的逻辑
return "default";
}
4. 语句组织原则
// 相关语句组织在一起
const user = getUserData();
const permissions = getPermissions(user);
const roles = getUserRoles(user);
// 分离不同职责
validateUserData(user);
processUserLogin(user, permissions);
logUserActivity(user, "login");
性能考虑
语句优化
// 避免重复计算
// 不佳
for (let i = 0; i < array.length; i++) {
if (expensive.calculation.result > threshold) {
process(array[i]);
}
}
// 更好
const threshold = expensive.calculation.result;
const length = array.length;
for (let i = 0; i < length; i++) {
if (threshold > comparisonValue) {
process(array[i]);
}
}
减少分支复杂度
// 复杂的嵌套语句
if (user) {
if (user.active) {
if (user.permissions) {
if (user.permissions.read) {
return processRead(user);
}
}
}
}
// 简化的早期返回
if (!user || !user.active) return null;
if (!user.permissions || !user.permissions.read) return null;
return processRead(user);