当前位置: 首页 > ds >正文

JavaScript ES6+ 最佳实践

1. 变量声明:从 varlet/const

问题代码var 存在变量提升,只有函数作用域,没有块级作用域,容易导致变量污染。

// 变量提升导致意外行为
console.log(num); // undefined 而非报错
var num = 10;
// 没有块级作用域
var name = '张三';
if (true) {var name = '李四'; // 覆盖外部作用域的name
}
console.log(name); // 输出 '李四'for (var i = 0; i < 5; i++) {setTimeout(function() {console.log(i); // 输出5个5}, 100);
}

ES6+ 解决方案

const name = '张三'; // 不可重新赋值的常量
if (true) {let name = '李四'; // 块级作用域
}
console.log(name); // '张三'for (let i = 0; i < 5; i++) {setTimeout(() => console.log(i), 100); // 0,1,2,3,4
}

最佳实践

  • 默认使用 const
  • 需要重新赋值时使用 let
  • 避免使用 var
2. 函数定义:从函数表达式到箭头函数

问题代码:冗长的语法,this 绑定问题。

var add = function(a, b) {return a + b;
};var obj = {value: 1,increment: function() {var self = this;setTimeout(function() {self.value++;}, 100);}
};

ES6+ 解决方案

const add = (a, b) => a + b;const obj = {value: 1,increment() {setTimeout(() => {this.value++;}, 100);}
};

特性

  • 箭头函数继承外层 this
  • 方法简写语法
  • 隐式返回
3. 异步编程:从回调地狱到 Promise/async-await

问题代码

getData(function(a) {getMoreData(a, function(b) {getEvenMoreData(b, function(c) {getFinalData(c, function(result) {console.log('Result:', result);}, failCallback);}, failCallback);}, failCallback);
}, failCallback);

ES6+ 解决方案

// Promise 链
getData().then(a => getMoreData(a)).then(b => getEvenMoreData(b)).then(c => getFinalData(c)).then(result => console.log('Result:', result)).catch(error => console.error(error));// async、await
async function processData() {try {const a = await getData();const b = await getMoreData(a);const c = await getEvenMoreData(b);const result = await getFinalData(c);console.log('Result:', result);} catch (error) {console.error(error);}
}

优势

  • 线性代码结构
  • 统一错误处理
  • 更好的可读性
4. 参数处理:从 arguments 到剩余参数

问题代码

function sum() {var args = Array.prototype.slice.call(arguments);return args.reduce(function(total, num) {return total + num;}, 0);
}

ES6+ 解决方案

function sum(...numbers) {return numbers.reduce((total, num) => total + num, 0);
}

特点

  • 真正的数组
  • 更清晰的参数定义
  • 可与普通参数混用
5. 面向对象:从构造函数到类语法

问题代码

function Person(name) {this.name = name;
}
Person.prototype.sayHello = function() {console.log('Hello, ' + this.name);
};

ES6+ 解决方案

class Person {constructor(name) {this.name = name;}sayHello() {console.log(`Hello, ${this.name}`);}// 静态方法static create(name) {return new Person(name);}
}

新增特性

  • 继承 (extends)
  • 静态方法
  • 私有字段 (#field)
  • 静态块
6. 字符串处理:从拼接符到模板字符串

问题代码

var name = '张三';
var age = 25;
var message = name + '今年' + age + '岁';

ES6+ 解决方案

const message = `${name}今年${age}`;

高级用法

// 多行字符串
const html = `
<div><h1>${title}</h1><p>${content}</p>
</div>
`;// 标签模板
function highlight(strings, ...values) {return strings.reduce((result, str, i) => `${result}${str}<span class="highlight">${values[i] || ''}</span>`, '');
}
const output = highlight`Hello ${name}, welcome to ${siteName}!`;
7. 对象和数组处理:从手动操作到展开运算符

问题代码

var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var combined = arr1.concat(arr2);var obj1 = { a: 1, b: 2 };
var obj2 = { b: 3, c: 4 };
var merged = Object.assign({}, obj1, obj2);

ES6+ 解决方案

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const merged = { ...obj1, ...obj2 };

实用技巧

// 数组复制
const copy = [...original];// 对象属性覆盖
const defaults = { color: 'red', size: 'medium' };
const config = { ...defaults, ...userConfig };// 剩余参数解构
const { a, b, ...rest } = { a: 1, b: 2, c: 3, d: 4 };
8. 数组迭代:从 for 循环到高阶函数

问题代码

var numbers = [1, 2, 3, 4];
var doubled = [];
for (var i = 0; i < numbers.length; i++) {doubled.push(numbers[i] * 2);
}

ES6+ 解决方案

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(num => num * 2);

常用高阶函数

// 过滤
const evens = numbers.filter(n => n % 2 === 0);// 累加
const sum = numbers.reduce((total, num) => total + num, 0);// 查找
const firstEven = numbers.find(n => n % 2 === 0);// 检查
const allPositive = numbers.every(n => n > 0);
const hasNegative = numbers.some(n => n < 0);
9. 模块系统:从 IIFE 到 ES Modules

问题代码

// math.js
(function() {function add(a, b) { return a + b; }function subtract(a, b) { return a - b; }window.math = { add: add, subtract: subtract };
})();// app.js
math.add(1, 2);

ES6+ 解决方案

// math.js
export function add(a, b) { return a + b; }
export function subtract(a, b) { return a - b; }// app.js
import { add } from './math.js';
add(1, 2);

现代模块特性

  • 命名导出/默认导出
  • 动态导入 (import())
  • 顶层 await
  • 模块元信息 (import.meta)
10. 其他重要 ES6+ 特性

解构赋值

// 对象解构
const { name, age } = person;
const { name: personName, age: personAge } = person;// 数组解构
const [first, second] = numbers;
const [head, ...tail] = numbers;

可选链 (?.) 和空值合并 (??)

// 避免 Cannot read property 'x' of undefined/null
const street = user?.address?.street ?? 'Unknown';// 函数调用可选链
someInterface.customMethod?.();

BigInt

const bigNumber = 9007199254740991n;
const biggerNumber = bigNumber + 1n;

全局对象标准化

// 浏览器环境
globalThis === window; // true// Node.js 环境
globalThis === global; // true
11.类型系统缺陷

原始问题

// 1. typeof null === 'object'
typeof null; // "object" (从JS诞生就存在的bug)// 2. 隐式类型转换
[] + {}; // "[object Object]"
{} + []; // 0// 3. == 的强制类型转换
'0' == false; // true

现代化实践

// 1. 使用 Object.prototype.toString 检测类型
Object.prototype.toString.call(null); // "[object Null]"// 2. 避免隐式转换,使用显式转换
Number([]) + Number({}); // NaN// 3. 始终使用 ===
'0' === false; // false
http://www.xdnf.cn/news/4561.html

相关文章:

  • 将Dify平台开发的工作流集成到Open WebUI中
  • 金融小知识
  • 【实战教程】零基础搭建DeepSeek大模型聊天系统 - Spring Boot+React完整开发指南
  • ChromaDB调用BGE模型的两种实践方式
  • 学习基本开锁知识
  • 【一篇详解】深入浅出RabbtiMQ消息队列
  • 阿里云平台与STM32的物联网设计
  • Python训练营打卡DAY18
  • 电气工程中漏源电压Vds的平台电压是什么?
  • 芳草集精油怎么样?佰草集精油的功效与用法一览
  • 利用相场法来求解任意脆性断裂问题
  • Notepad++中XML格式化插件介绍
  • Ubuntu安装pgsql
  • Golang 接口 vs Rust Trait:一场关于抽象的哲学对话
  • Qt 中信号与槽(signal-slot)机制支持 多种连接方式(ConnectionType)
  • Web 架构之负载均衡全解析
  • vue+vite难点和优化,及seo优化
  • 品质领航家装时代,亚新丽以匠心雕琢每一寸美好
  • GPT与LLaMA:两大语言模型架构的深度解析与对比
  • Kafka的消息保留策略是怎样的? (基于时间log.retention.hours或大小log.retention.bytes,可配置删除或压缩策略)
  • 强缓存与协商缓存的实现机制
  • AKS 网络深入探究:Kubenet、Azure-CNI 和 Azure-CNI(overlay)
  • 基于LVS实现负载均衡,对NAT模式的介绍和使用案例
  • LeetCode第190题_颠倒二进制位
  • 云蝠智能大模型语音交互智能体赋能电视台民意调研回访:重构媒体数据采集新范式
  • 2:点云处理—3D相机开发
  • 如何在Idea中编写Spark程序并运行
  • 【Bug经验分享】SourceTree用户设置必须被修复/SSH 主机密钥未缓存(踩坑)
  • Windows_PyCharm Python语言开发环境构建
  • 常见dp问题的状态表示