在前端编程中,高质量的代码不仅实现功能,还注重可读性、可维护性和性能。以下是一些值得品味和学习的优质前端代码片段,涵盖了函数式编程、ES6新特性、以及一些最佳实践示例:
文章目录
1. 箭头函数与数组方法结合使用
const numbers =[1,2,3,4,5];const squared = numbers.map(number=> number * number);
console.log(squared);// 输出: [1, 4, 9, 16, 25]
这段代码展示了如何使用箭头函数和map方法简洁地对数组元素进行操作。
2. 解构赋值
const user ={firstName:'John',lastName:'Doe'};const{ firstName, lastName }= user;
console.log(`${firstName}${lastName}`);// 输出: John Doe
解构赋值使得从对象或数组中提取值变得非常直观和简洁。
3. 模板字符串
const name ='Alice';const greeting =`Hello, ${name}! Welcome to our website.`;
console.log(greeting);// 输出: Hello, Alice! Welcome to our website.
模板字符串提供了一种更自然的方式来插入变量和表达式到字符串中,增强了代码的可读性。
4. 使用Set去重
const array =[1,2,2,3,4,4,5];const uniqueArray =[...newSet(array)];
console.log(uniqueArray);// 输出: [1, 2, 3, 4, 5]
利用
Set
数据结构的唯一性,可以优雅地去除数组中的重复元素。
5. Promise链式调用
fetch('https://api.example.com/data').then(response=> response.json()).then(data=> console.log(data)).catch(error=> console.error('Error:', error));
展示了如何使用
Promise
来处理异步操作,保持代码结构清晰,易于理解和维护。
6. 立即执行函数表达式(IIFE)用于模块化
(function(){const privateVar ='I am private';
window.myModule ={publicMethod:function(){
console.log(privateVar);}};})();
myModule.publicMethod();// 输出: I am private
IIFE用来创建作用域,避免全局污染,是早期
JavaScript
中实现模块化的一种方式。
7. 使用默认参数和Rest参数
functiongreet(name ='Guest',...greetings){
greetings.forEach(greeting=> console.log(`${greeting}, ${name}!`));}greet('Alice','Hello','Welcome');// 输出:// Hello, Alice!// Welcome, Alice!
默认参数使得函数调用更加灵活,而
Rest
参数允许你将不确定数量的参数作为一个数组传入。
8.时间函数 - 格式化日期
functionformatDate(date){const options ={year:'numeric',month:'long',day:'numeric'};returnnewDate(date).toLocaleDateString('zh-CN', options);}
console.log(formatDate(newDate()));// 输出:如 "2023年4月16日"
9.文件上传 - 预览图片
<input type="file" id="imageFile" accept="image/*"/><img id="preview" src="#" alt="Image preview" style="display:none;"/><script>
document.getElementById('imageFile').addEventListener('change',(e)=>{const file = e.target.files[0];if(file){const reader =newFileReader();
reader.onload=(event)=>{
document.getElementById('preview').src = event.target.result;
document.getElementById('preview').style.display ='block';};
reader.readAsDataURL(file);}});</script>
10.单行与多行文本省略
单行与多行文本省略
<pclass="single-line-ellipsis">这是一个很长很长的句子,可能会超出容器的宽度。</p>
.single-line-ellipsis {width: 200px;
white-space: nowrap;overflow: hidden;
text-overflow: ellipsis;}
多行文本省略
<pclass="multi-line-ellipsis">这里是一个多行文本的例子,它将会在超过指定行数后被省略显示,以保持界面的整洁。</p>
.multi-line-ellipsis {display:-webkit-box;-webkit-line-clamp:3;/* 显示行数 */-webkit-box-orient: vertical;overflow: hidden;}
11.动画效果 - 使用requestAnimationFrame实现平滑滚动
functionsmoothScroll(target, duration){const start = window.pageYOffset;const distance = target.getBoundingClientRect().top;const startTime = performance.now();functionstep(currentTime){const timeElapsed = currentTime - startTime;const progress = Math.min(timeElapsed / duration,1);
window.scrollTo(0, start + distance * progress);if(timeElapsed < duration){requestAnimationFrame(step);}}requestAnimationFrame(step);}// 使用方法:平滑滚动到页面顶部smoothScroll(document.documentElement,1000);
12.DOM操作 - 动态创建与插入元素
functioncreateElementWithText(tag, text){const element = document.createElement(tag);
element.textContent = text;return element;}const div =createElementWithText('div','新创建的Div元素');
document.body.appendChild(div);
13.异步- async/await处理异步操作
asyncfunctionfetchUserData(userId){try{const response =awaitfetch(`https://api.example.com/users/${userId}`);if(!response.ok)thrownewError(`HTTP error! status: ${response.status}`);const userData =await response.json();
console.log(userData);}catch(error){
console.error('There was a problem with the fetch operation:', error);}}fetchUserData(123);
14.ES6解构与展开运算符 - 快速交换变量值
let a =1;let b =2;[a, b]=[b, a];
console.log(a, b);// 输出: 2 1
15.Promise.allSettled 与并发请求管理
使用
Promise.allSettled
处理多个异步操作,无论这些操作成功还是失败,都能获取到每个操作的结果。
asyncfunctionfetchResources(urls){const promises = urls.map(url=>fetch(url).then(response=>({status:'fulfilled',value: response
})).catch(error=>({status:'rejected',reason: error
})));return Promise.allSettled(promises);}const urls =['https://api.example.com/data1','https://api.example.com/data2'];fetchResources(urls).then(results=>{
results.forEach((result, index)=>{if(result.status ==='fulfilled'){
console.log(`Resource ${index +1} fetched successfully.`);}else{
console.error(`Failed to fetch resource ${index +1}:`, result.reason);}});});
16.使用 async/await 和 try/catch 进行错误处理
优雅地处理异步操作中的错误,提高代码可读性。
asyncfunctionfetchData(id){try{const response =awaitfetch(`https://api.example.com/items/${id}`);if(!response.ok)thrownewError(`HTTP error! status: ${response.status}`);const data =await response.json();
console.log(data);}catch(error){
console.error('There was a problem fetching the data:', error);}}fetchData(123)
17.生成器函数与迭代协议
function*fibonacci(){let prev =0, curr =1;while(true){[prev, curr]=[curr, prev + curr];yield curr;}}const fibGen =fibonacci();
console.log(fibGen.next().value);// 1
console.log(fibGen.next().value);// 1
console.log(fibGen.next().value);// 2
18.使用Map和Set进行高效数据操作
利用
ES6
的
Map
和
Set
数据结构来解决特定问题,提高代码效率。
const map =newMap();
map.set('apple',1);
map.set('banana',2);
console.log(map.get('apple'));// 输出: 1const set =newSet([1,2,3,9,5,2]);
console.log([...newSet([...set].filter(x=> x %2===0))]);// 输出去重后的偶数集合: [2, 4]
19.防抖(debounce)函数 - 减少高频触发的函数调用
functiondebounce(func, wait){let timeout;returnfunction(...args){clearTimeout(timeout);
timeout =setTimeout(()=>func.apply(this, args), wait);};}const handleResize =debounce(function(){
console.log('窗口大小已调整');},300);
window.addEventListener('resize', handleResize);
20.限制并发
/**
* 异步并发控制函数
*
* @param {number} poolLimit - 并发执行的最大任务数量
* @param {Iterable<any>} iterable - 包含待执行任务输入的可迭代对象
* @param {(item: any, index: number) => Promise<any>} iteratorFn - 异步任务处理器,接收迭代对象的元素和其索引为参数
* @returns {Promise<any[]>} - 所有异步任务完成后的结果数组
*/asyncfunctionasyncPool(poolLimit, iterable, iteratorFn){// 结果数组,用于收集所有异步任务的完成结果const results =[];// 正在执行的任务集合,使用Set以便快速查找和删除const executing =newSet();// 遍历可迭代对象for(const[index, item]of iterable.entries()){// 构建异步任务Promise,并立即执行const taskPromise =(async()=>{try{// 执行异步任务并等待结果const result =awaititeratorFn(item, index);
results[index]= result;// 根据索引位置填充结果数组}finally{// 无论任务成功还是失败,都要从执行集合中移除
executing.delete(taskPromise);}})();// 添加到执行集合
executing.add(taskPromise);// 控制并发数量,当达到限制时等待任何一个任务完成if(executing.size >= poolLimit){await Promise.race(executing);}}// 确保所有任务(即使在循环结束时尚未启动的)都完成await Promise.all(executing);return results;}// 示例使用(async()=>{// 模拟异步任务函数,参数i模拟不同的延迟时间constdelayAsync=(i)=>newPromise(resolve=>setTimeout(()=>resolve(`Task ${i} done after ${i}ms`), i));// 调用asyncPool控制并发执行const results =awaitasyncPool(2,[1000,2000,500,1500], delayAsync);
console.log(results);})();
21.解构赋值与默认值结合
functionwelcomeUser({ name ='Guest', role ='Visitor'}){
console.log(`Welcome, ${name} (${role})!`);}welcomeUser({name:'Alice'});// 输出: Welcome, Alice (Visitor)!welcomeUser({});// 输出: Welcome, Guest (Visitor)!
22.扁平化数组与映射
const nestedArray =[[1,2],[3,4],[5]];const flatMappedArray = nestedArray.flat().map(item=> item *2);
console.log(flatMappedArray);// 输出: [2, 4, 6, 8, 10]
23.使用Proxy进行对象属性访问的监控
const person ={name:'Alice',age:30};const personProxy =newProxy(person,{get(target, prop){
console.log(`Accessing property: ${prop}`);return target[prop];},set(target, prop, value){
console.log(`Setting property ${prop} to ${value}`);
target[prop]= value;returntrue;}});
personProxy.name;// 输出: Accessing property: name
personProxy.age =31;// 输出: Setting property age to 31
24.利用Symbol实现私有属性
const _secret =Symbol('secret');classSecretHolder{constructor(secret){this[_secret]= secret;}revealSecret(){returnthis[_secret];}}const instance =newSecretHolder('classified information');
console.log(instance.revealSecret());// 输出: classified information// 注意:直接访问_secret属性是不可见的,保护了私有性
25.利用async iterators处理异步流
asyncfunction*generateNumbers(limit){for(let i =1; i <= limit; i++){awaitnewPromise(resolve=>setTimeout(resolve,1000));// 模拟异步yield i;}}(async()=>{forawait(const num ofgenerateNumbers(5)){
console.log(num);}})();// 每秒输出一个数字,从1到5
26.使用CSS Custom Properties(变量)进行主题切换
CSS变量不仅简化了样式管理,还便于实现动态主题切换功能。
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Theme Switcher</title><style>:root{--primary-color: #3f51b5;--secondary-color: #f50057;--text-color: #ffffff;}body{color:var(--text-color);background:var(--primary-color);}.button{background-color:var(--secondary-color);color:var(--text-color);border-radius: 4px;padding: 10px 20px;transition: background-color 0.3s ease;}.button:hover{background-color:darken(var(--secondary-color), 10%);}/* 假设有一个按钮用于切换主题 */.toggle-button{cursor: pointer;}/* 主题切换示例 */.dark-theme{--primary-color: #212121;--secondary-color: #9c27b0;}</style></head><body><buttonclass="button toggle-button">Toggle Dark Theme</button><script>// 这里需要JavaScript来实际切换主题类
document.querySelector('.toggle-button').addEventListener('click',function(){
document.body.classList.toggle('dark-theme');});</script></body></html>
版权归原作者 水煮白菜王 所有, 如有侵权,请联系我们删除。