JavaScript中的一些实用小方法
<p><strong>1. 控制台console的使用</strong></p><p>使用场景: 改进调试复杂对象的日志记录。console.table、console.group 和 console.time 等控制台方法可以提供更结构化、更 informative 的调试信息。</p>
<p><em>// 基本日志记录</em><br>
console.log('简单日志');<br>
console.error('这是一个错误');<br>
console.warn('这是一个警告');<br>
<br>
<em>// </em><em>记录表格数据</em><br>
const users = [<br>
{ name: 'John', age: 30, city: 'New York' },<br>
{ name: 'Jane', age: 25, city: 'San
Francisco' },<br>
];<br>
console.table(users);<br>
<br>
<em>// </em><em>分组日志</em><br>
console.group('用户详细信息');<br>
console.log('用户 1: John');<br>
console.log('用户 2: Jane');<br>
console.groupEnd();<br>
<br>
<em>// </em><em>计时代码执行</em><br>
console.time('计时器');<br>
for (let i = 0; i < 1000000; i++) {<br>
<em>// </em><em>一些繁重的计算</em><br>
}<br>
console.timeEnd('计时器');<br>
<br>
</p>
<p><strong>2. 不使用临时变量来交换变量的值</strong></p>
<p>例如我们想要将 a 于 b 的值交换</p>
<p>let a = 1, b = 2;<br>
<br>
<em>// </em><em>交换值</em><br>
= ;<br>
<br>
<em>// </em><em>结果: a = 2, b = 1</em><br>
<br>
</p>
<p>这行代码使用数组解构赋值的方式来交换两个变量的值</p>
<p><strong>3. 浅克隆对象</strong></p>
<p>const originalObj = { name: '张三', age: 24 };<br>
<br>
const clonedObj = { ...originalObj };<br>
<br>
<em>// </em><em>结果: clonedObj = { name: '张三', age: 24 }</em><br>
<em>// </em><em>此时改变 clonedObj 的属性,将不会影响到原始对象 originalObj</em><br>
<br>
</p>
<p>通过使用扩展运算符 (...) 创建originalObj的浅克隆对象。</p>
<p><strong>4. 合并对象</strong></p>
<p>const obj1 = { name: '张三' };<br>
const obj2 = { age: 22 };<br>
<br>
const mergedObj = { ...obj1, ...obj2 };<br>
<br>
<em>// </em><em>结果: mergedObj = { name: '张三', age: 22 }</em><br>
<br>
</p>
<p>与克隆类似,通过扩展运算符将obj1和合并obj2为一个新的对象。如果有重叠的属性,则最后一个对象的属性将覆盖前一个对象的属性。</p>
<p><strong>5. find和findIndex的使用</strong></p>
<p>需要找到第一个满足特定条件的元素?find()是你的救星。</p>
<p>它会返回第一个通过回调函数测试的元素的值,非常适合快速查找和避免遍历整个数组。</p>
<p>示例: 找到第一个大于3的元素</p>
<p>const numbers = ;<br>
<br>
const firstGreaterThanThree = numbers.find(number => number
> 3);<br>
console.log(firstGreaterThanThree);<br>
<br>
<em>// </em><em>输出: 4</em><br>
<br>
</p>
<p>findIndex()比find()更进一步,它会返回第一个通过回调函数测试的元素的索引。</p>
<p>这在查找数组中的特定数据、根据元素在数组中的位置修改元素,以及执行针对性的操作时非常有用。</p>
<p>示例: 找到第一个大于3的元素的索引</p>
<p>const numbers = ;<br>
<br>
const indexOfFirstGreaterThanThree = numbers.findIndex(number => number
> 3);<br>
console.log(indexOfFirstGreaterThanThree);<br>
<br>
<em>// </em><em>输出: 2</em><br>
<br>
</p>
<p><strong>6. 将 NodeList 转换为数组</strong></p>
<p>const nodesArray = [ ...document.querySelectorAll('div')
];<br>
<br>
</p>
<p>通过扩展运算符将NodeList( document.querySelectorAll函数的返回值) 转换为 JavaScript 数组,从而能够使用数组的map方法filter去操作查找到的元素。</p>
<p><strong>7. forEach遍历数组</strong></p>
<p>forEach()就像一位可靠的助手,可以遍历数组中的每个元素,并执行你指定的任务。</p>
<p>它接受一个回调函数,该函数会对每个元素执行操作,非常适合处理副作用,例如日志记录、DOM操作和数据修改。</p>
<p>示例: 打印数组中的所有元素</p>
<p>const fruits = ["apple", "banana", "cherry"];<br>
<br>
fruits.forEach(fruit =>console.log(fruit));<br>
<br>
</p>
<p><strong>8. 数组去重复项</strong></p>
<p>const arr = ;<br>
<br>
const unique = [...newSet(arr)];<br>
<br>
<em>// </em><em>结果: unique = </em><br>
<br>
</p>
<p>这里利用了Set对象存储的值会保持唯一,以及扩展运算符能将Set转换回数组的特性。这是一种优雅的删除数组中重复项的方式。</p>
<p><strong>9. 根据指定条件判断,是否给对象的属性赋值</strong></p>
<p>const condition = true;<br>
const value = '你好,世界';<br>
<br>
<em>// </em><em>如果条件为真,则将 value 变量的值赋给 newObject.key 属性</em><br>
const newObject = {...(condition && {key: value})};<br>
<br>
<em>// </em><em>结果: newObject = { key: '你好,世界' }</em><br>
<br>
</p>
<p>此案例使用扩展运算符 (...) 与短路求值(&&),将属性有条件地添加到对象中。 如果condition为真,则会将{key: value}扩展到对象中;否则不进行任何操作。</p>
<p><strong>10. 使用变量作为对象的键</strong></p>
<p>const dynamicKey = 'name';<br>
const value = '张三';<br>
<br>
<em>// </em><em>使用一个动态的变量作为 key</em><br>
const obj = {: value};<br>
<br>
<em>// </em><em>结果: obj = { name: '张三' }</em><br>
<br>
</p>
<p>这种语法称为计算属性名,它允许使用变量作为对象的键。方括号内的dynamicKey表达式会计算其值,以将其用作属性名称。</p>
<p><strong>11. 离线状态检查器</strong></p>
<p>const isOnline =
navigator.onLine ? '在线' : '离线';<br>
<br>
<em>// </em><em>结果: isOnline = '在线'
或 '离线'</em><br>
<br>
</p>
<p>这段代码使用三元运算符检查浏览器的在线状态(navigator.onLine),如果为真则返回'在线',否则返回'离线'。这是一种动态检查用户网络连接状态的方法。</p>
<p><strong>12. 将 url 问号后面的查询字符串转为对象</strong></p>
<p>const query = 'name=John&age=30';<br>
<br>
<em>// </em><em>将字符串解析为对象</em><br>
const parseQuery = query => Object.fromEntries(new URLSearchParams(query));<br>
<br>
<em>// </em><em>结果: parseQuery = { name: 'John', age: '30'
}</em><br>
<br>
</p>
<p>此示例将一个查询字符串转换为了一个对象。其中URLSearchParams会进行字符串解析,它将返回一个可迭代对象,然后在通过Object.fromEntries将它转换为对象,从而使 URL 参数检索变得方便多了。</p>
<p><strong>13. 将秒数转换为时间格式的字符串</strong></p>
<p>const seconds = 3661; <em>// </em><em>一小时是 3600 秒,多出 61 秒</em><br>
<br>
const toTimeString = seconds => newDate(seconds*1000).toISOString().substr(11, 8);<br>
<br>
toTimeString(seconds));<br>
<br>
<em>// </em><em>结果: '01:01:01'</em><br>
<br>
</p>
<p>此示例将秒数转换为 HH:MM:SS 格式的字符串。它通过给定的秒数加上时间戳起始点来创建一个新的 Date 对象,然后将其转换为 ISO 字符串,并提取时间部分得到结果。</p>
<p><strong>14. 求某对象所有属性值的最大值</strong></p>
<p><em>// 数学、语文、英语成绩</em><br>
const scores = { math: 95, chinese: 99, english: 88 };<br>
<br>
const maxObjectValue = obj => Math.max(...Object.values(obj));<br>
<br>
<em>// </em><em>最高分</em><br>
maxObjectValue(scores));<br>
<br>
<em>// </em><em>结果: 99</em><br>
<br>
</p>
<p>此示例用于在对象所有的属性值中找到最大值。其中Object.values(obj)将对象所有的属性值提取为数组,然后使用展开运算符将数组的所有元素作为Math.max函数的参数进行最大值查找。</p>
<p><strong>15. 判断对象的值中是否包含有某个值</strong></p>
<p>const person = { name: '张三', age: 30 };<br>
<br>
const hasValue = (obj, value) => Object.values(obj).includes(value);<br>
<br>
hasValue(person, 30);<br>
<br>
<em>// </em><em>结果: true</em><br>
<br>
</p>
<p>hasValue函数会检查对象的值中是否存在指定的值。其中Object.values(obj)用于获取对象中所有的值的数组,然后通过includes(value)检查指定值是否在该数组中。</p>
<p><strong>16. 安全访问深度嵌套的对象属性</strong></p>
<p>const user = { profile:
{ name: '张三' } };<br>
<br>
const userName = user.profile?.name ?? '匿名';<br>
<br>
<em>// </em><em>结果: userName = '张三'</em><br>
<br>
</p>
<p>此代码首先演示了如何使用可选链运算符 (?.) 安全地访问user.profile的name值。如果user.profile是undefined或null,它会短路并返回undefined,从而避免潜在的类型错误TypeError。</p>
<p>然后,使用空值合并运算符 (??) 检查左侧是否为null或undefined,如果是,则使用默认值'匿名'。这可确保后备值不会是其他假值(如''或0)。这对于访问数据结构中可能不存在某些中间属性的深层嵌套属性非常有用。</p>
<p>在 JavaScript 中,空值合并运算符 (??) 和逻辑或 (||) 都可以用于提供默认值,但它们处理假值的方式有所不同。</p>
<p>在上面的例子中,如果把??改为||,行为会稍微有些不同。||的左侧如果为假值,它将会返回右侧的值。JavaScript 中的假值包括null、undefined、0、NaN、''(空字符串)和false。这意味着||左边的值不仅仅是null或undefined,如果还是其他假值,那么都将返回右侧的值。</p>
<p><strong>17. 条件执行语句</strong></p>
<p>const isEligible = true;<br>
<br>
isEligible && performAction();<br>
<br>
<em>// </em><em>如果 isEligible 为真,则调用 performAction()</em><br>
<br>
</p>
<p>利用逻辑 AND ( &&) 运算符,函数performAction()仅会在isEligible结果为true时执行。这是一种无需if语句即可有条件地执行函数的简介语法。这对于根据某些条件执行函数非常有用,尤其是在事件处理或回调中。</p>
<p>如果想要条件赋值,则可以这样写</p>
<p>const isEligible = true;<br>
let value = '';<br>
<br>
<em>// </em><em>需要将赋值语句用用括号括起来</em><br>
isEligible && (value = '条件达成');<br>
<br>
<em>// </em><em>如果 isEligible 为真,则执行 (value = '条件达成') 语句</em><br>
<br>
</p>
<p><strong>18. 创建包含值为指定数字范围的数组</strong></p>
<p>例如创建数字5以内所有正数的数组</p>
<p>const range = Array.from({ length: 5 }, (_,
i) => i + 1);<br>
<br>
<em>// </em><em>结果: range = </em><br>
<br>
</p>
<p>Array.from()从类数组或可迭代对象创建一个新数组。这里,它接受一个具有属性length和映射函数的对象。映射函数 ( (_, i) => i +
1) 使用索引 ( i) 生成从 1 到 5 的数字。下划线 ( _) 是一种惯例,表示未使用该参数。</p>
<p><strong>19. 提取文件扩展名</strong></p>
<p>const fileName = 'example.png';<br>
<br>
const getFileExtension = str => str.slice(((str.lastIndexOf(".")
- 1) >>> 0) + 2);<br>
<br>
<em>// </em><em>结果: getFileExtension = 'png'</em><br>
<br>
</p>
<p>这个案例实现了从字符串中提取文件扩展名。它先找到最后一次出现点号 (.) 位置,然后截取从该位置到末尾的字符串。位运算符 (>>>) 确保了即使未找到点号 (.) ,操作也是安全的,因为在这种情况下仍然会返回一个空字符串。</p>
<p><strong>20. 切换元素的 class</strong></p>
<p>const element = document.querySelector('.my-element');<br>
<br>
const toggleClass = (el, className) => el.classList.toggle(className);<br>
<br>
toggleClass(element, 'active');<br>
<br>
</p>
<p>toggleClass函数使用classList.toggle()方法从一个元素的 class 列表中添加或移除某个 class。如果该 class 存在,则删除,否则添加。这是一种根据用户交互或应用程序状态动态更新
class 的方法。非常适合实现响应式设计元素,例如菜单根据用户操作显示或隐藏。</p>
<p><strong>21. 数组的map方法</strong></p>
<p>需要根据现有数组创建一个新的数组,并进行一些修改?map()可以帮到你。</p>
<p>它会根据回调函数对每个元素进行操作,并返回一个包含结果的新数组。</p>
<p>它非常适合提取数据集、提供数据和执行计算。</p>
<p>示例: 将数组中的每个数字翻倍</p>
<p>const numbers = ;<br>
<br>
const doubledNumbers = numbers.map(number => number * 2);<br>
console.log(doubledNumbers);<br>
<br>
<em>// </em><em>输出 </em><br>
<br>
</p>
<p><strong>22. 数组的filter方法</strong></p>
<p>想象一下,有人在门口把守,只允许特定的人进入VIP区域。 filter()的功能类似,它会创建一个新数组,只包含通过回调函数测试的元素。</p>
<p>你可以用它根据条件筛选数据、删除不需要的元素,或创建自定义子集。</p>
<p>示例: 从数组中获取偶数</p>
<p>const numbers = ;<br>
<br>
const evenNumbers = numbers.filter(number => number % 2 === 0);<br>
console.log(evenNumbers); <br>
<br>
<em>// </em><em>输出 </em><br>
<br>
</p>
<p><strong>23. 数组的reduce方法</strong></p>
<p>reduce()就像一位武林高手,可以将整个数组整合为一个单一的值,并使用回调函数进行操作。</p>
<p>它非常灵活,可以计算总和、平均值,找到最大值和最小值,甚至创建复杂的数据结构。</p>
<p>示例: 计算数组的总和</p>
<p>const numbers = ;<br>
<br>
const sum = numbers.reduce((accumulator, current) => accumulator +
current, 0);<br>
console.log(sum); <br>
<br>
<em>// </em><em>输出: 10</em><br>
<br>
</p>
<p><strong>24. 数组的some方法</strong></p>
<p>你是否需要检查数组中是否存在至少一个满足特定条件的元素?some()可以帮到你。</p>
<p>它会检查是否存在至少一个元素通过回调函数测试。</p>
<p>你可以用它来确认条件、验证输入,或者在只需要一个匹配元素时简化逻辑。</p>
<p>示例: 检查数组中是否存在大于10的元素</p>
<p>const numbers = ;<br>
<br>
const hasElementGreaterThanTen = numbers.some(number => number
> 10);<br>
console.log(hasElementGreaterThanTen);<br>
<br>
<em>// </em><em>输出: true</em><br>
<br>
</p>
<p><strong>25. 数组的every方法</strong></p>
<p>every()是some()的严格的兄长。它会确保数组中的所有元素都通过回调函数测试。</p>
<p>这对于数据验证、检查所有元素是否符合指定结构,以及进行质量检查非常有用。</p>
<p>示例: 检查数组中的所有元素是否都是字符串</p>
<p>const data = ["apple", "banana", 10];<br>
<br>
const allStrings = data.every(element =>typeof element
=== "string");<br>
console.log(allStrings);<br>
<br>
<em>// </em><em>输出: false</em><br>
<br>
</p>
<p><strong>26. 数组的includes方法</strong></p>
<p>有时你只需要知道数组中是否存在特定值。 includes()是进行简单验证的最佳助手。</p>
<p>它会快速检查给定值是否存在于数组中,这对于识别单个数据点或根据数组成员资格创建条件逻辑非常重要。</p>
<p>示例: 检查数组中是否包含值
"orange"</p>
<p>const fruits = ["apple", "banana", "cherry"];<br>
<br>
const hasOrange = fruits.includes("orange");<br>
console.log(hasOrange);<br>
<br>
<em>// </em><em>输出: false</em><br>
<br>
</p>
<p><strong>27. 数组的flat方法</strong></p>
<p>你是否遇到过多维数组或数组嵌套在数组中的情况?它们可能很混乱。flat()可以将它们转换为一维数组。</p>
<p>这对于简化嵌套数组、处理可能具有嵌套结构的API数据,以及存储数据以便进一步处理非常有用。</p>
<p>示例: 扁平化嵌套数组</p>
<p>const nestedArray = , 4];<br>
<br>
const flattenedArray = nestedArray.flat();<br>
console.log(flattenedArray);<br>
<br>
<em>// </em><em>输出: </em><br>
<br>
</p>
<p>提示: 考虑使用flatMap(),这是JavaScript的另一个新功能,它可以让你更好地控制扁平化和转换操作。</p>
<p><strong>28. 记忆化</strong></p>
<p>记忆化是一种优化技术,它涉及缓存昂贵函数调用的结果,并在再次出现相同输入时返回缓存的结果。这可以显著提高计算量大的函数的性能,特别是那些频繁使用相同参数调用的函数。</p>
<p>使用场景: 提高递归函数(如斐波那契数列计算)的性能。如果没有记忆化,对斐波那契函数的每次调用都会多次冗余地计算相同的值,导致时间复杂度呈指数级增长。</p>
<p>const memoize = (fn) =>
{ const cache = {}; return (...args) => {
const key = JSON.stringify(args); if (!cache)
{ cache = fn(...args); }
return cache; };};<br>
const fibonacci = memoize((n) => { if (n
<= 1) return n; return fibonacci(n - 1)
+ fibonacci(n - 2);});<br>
console.log(fibonacci(40)); // 102334155<br>
<br>
</p>
<p>为什么要用它: 避免冗余计算,显著提高具有重复输入的函数的性能。记忆化可以将低效的重复计算转换为可管理的线性时间操作,使其成为优化性能密集型任务的必要技术。</p>
<p><strong>29. Proxy 代理</strong></p>
<p>Proxy 对象允许你为另一个对象创建代理,使你能够拦截和重新定义基本操作,例如属性查找、赋值、枚举、函数调用等。这提供了一种强大的方式来向对象添加自定义行为。</p>
<p>使用场景: 在对象属性访问和赋值时进行验证和日志记录。例如,你可以强制执行类型约束并记录访问尝试,从而提供更好的控制和调试功能。</p>
<p>const user = { name: 'John', age: 30};<br>
const handler = { get: (target, prop) => {
console.log(`Getting ${prop}`); return target;
}, set: (target, prop, value) => { if (prop
=== 'age' && typeof value !== 'number')
{ throw new TypeError('Age must be a number');
} console.log(`Setting ${prop} to ${value}`);
target = value; return true; }};<br>
const proxyUser = new Proxy(user, handler);console.log(proxyUser.name); //
Getting name, JohnproxyUser.age = 35; // Setting age to 35//
proxyUser.age = '35'; // Throws TypeError<br>
<br>
</p>
<p> </p>
<p>为什么要用它: 允许为对象操作(例如验证、日志记录等)自定义行为,从而增强对对象操作的控制。代理还可以用于实现复杂的逻辑,例如访问控制和数据绑定。这使得它们成为管理和扩展对象行为的多功能工具。</p>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
<!--
博客签名HTML
Austin Liu 刘恒辉
Project Manager and Software Designer
E-Mail: lzhdim@163.com
Blog: http://lzhdim.cnblogs.com
Date: 2022-03-23 18:00:00
使用方法:
//在博客里添加该代码
-->
<br><br>
<table cellpadding="0" cellspacing="0" class="field" style="background-color: #EEE; width: 100%">
<tbody>
<tr>
<td align="center" width="110px"><img
height="100px" src="https://images.cnblogs.com/cnblogs_com/lzhdim/636184/o_230607054137_lzhdim.png"
width="100px"></td>
<td align="left">
<span style="font-size: 10pt; color: #223355"> Austin Liu 刘恒辉</span>
<br><span style="font-size: 10pt; color: #223355"> Project Manager and Software Designer</span><br><br>
<span style="font-size: 10pt; color: #223355"> E-Mail:lzhdim@163.com</span><br>
<span style="font-size: 10pt; color: #223355"> Blog:https://lzhdim.cnblogs.com<br></span><br>
<span style="font-size: 10pt; color: #223355">
欢迎收藏和转载此博客中的博文,但是请注明出处,给笔者一个与大家交流的空间。谢谢大家。<br></span>
</td>
</tr>
</tbody>
</table><br><br>
来源:https://www.cnblogs.com/lzhdim/p/18866385
頁:
[1]