10 個你可能不知道的高級 JavaScript 技術(shù)
共 12734字,需瀏覽 26分鐘
·
2024-09-17 17:00
JavaScript作為一種功能強(qiáng)大的開發(fā)語言,擁有許多隱藏的功能,可以幫助開發(fā)者提高開發(fā)效率和代碼整潔度。
本文將介紹10種你可能不知道的高級JavaScript技術(shù),幫助你提升編碼技能,寫出更優(yōu)雅、更高效的代碼。
1. 使用別名進(jìn)行解構(gòu)
解構(gòu)是一種將數(shù)組中的值或?qū)ο蟮膶傩越獍鼮椴煌兞康恼Z法糖。別名則允許你在解構(gòu)過程中重命名變量,這在處理來自外部來源(如API)的數(shù)據(jù)時特別有用。
● 用例
從API獲取數(shù)據(jù)時,你想為屬性分配更有意義的名稱,以提高代碼的可讀性和可維護(hù)性。
const apiResponse = {first_name: 'John',user_age: 30,address: {city: 'New York',zip: '10001'}};const {first_name: firstName,user_age: age,address: {city: hometown,zip: postalCode}} = apiResponse;console.log(firstName); // Johnconsole.log(age); // 30console.log(hometown); // New Yorkconsole.log(postalCode); // 10001
2. 柯里化
柯里化是將接受多個參數(shù)的函數(shù)轉(zhuǎn)換為一系列每個接受單個參數(shù)的函數(shù)的過程。
這種技術(shù)允許你創(chuàng)建更靈活和可重用的函數(shù),這在函數(shù)式編程中特別有用,可以大大簡化高度可重用的實用函數(shù)的創(chuàng)建,使代碼庫更簡潔、更易于維護(hù)。
● 用例
創(chuàng)建可重用和可配置的函數(shù)以應(yīng)用折扣??梢詣?chuàng)建一個柯里化函數(shù),而不必為不同的折扣百分比編寫單獨的函數(shù)。
const applyDiscount = (discount) => (price) => price - (price * discount / 100);const tenPercentOff = applyDiscount(10);const twentyPercentOff = applyDiscount(20);console.log(tenPercentOff(100)); // 90console.log(twentyPercentOff(100)); // 80const applyTax = (taxRate) => (price) => price + (price * taxRate / 100);const applyTenPercentTax = applyTax(10);console.log(applyTenPercentTax(100)); // 110console.log(applyTenPercentTax(twentyPercentOff(100))); // 88
3. 去抖動和節(jié)流
去抖動和節(jié)流是控制函數(shù)執(zhí)行頻率的技術(shù)。它們對于優(yōu)化事件處理程序和防止可能降低性能的過多函數(shù)調(diào)用特別有用。
去抖動可確保僅在上次調(diào)用函數(shù)后經(jīng)過一定時間后才調(diào)用該函數(shù)。這對于搜索輸入字段等場景很有用,在這些場景中,如果希望僅在用戶停止輸入后才進(jìn)行API調(diào)用。
● 用例
優(yōu)化搜索輸入字段以減少API調(diào)用次數(shù)。這可以防止服務(wù)器過載并通過僅在用戶完成輸入后啟動搜索來改善用戶體驗。
function debounce(func, delay) {let timeoutId;return function(...args) {clearTimeout(timeoutId);timeoutId = setTimeout(() => func.apply(this, args), delay);};}const search = debounce((query) => {console.log(`Searching for ${query}`);// Assume an API call here}, 300);document.getElementById('searchInput').addEventListener('input', (event) => {search(event.target.value);});
節(jié)流確保在指定時間段內(nèi)最多調(diào)用一次函數(shù)。通過確保以受控間隔調(diào)用函數(shù)來防止性能問題,減少瀏覽器負(fù)載并提供更好的用戶體驗。
這對于想要限制函數(shù)調(diào)用頻率的滾動事件等場景很有用。
● 用例
優(yōu)化滾動事件處理以獲得更好的性能。這可以防止瀏覽器因過多的事件調(diào)用而過載,從而確保更流暢、響應(yīng)更快的交互。
function throttle(func, interval) {let lastCall = 0;return function(...args) {const now = Date.now();if (now - lastCall >= interval) {lastCall = now;func.apply(this, args);}};}const handleScroll = throttle(() => {console.log('Scrolled');// Assume complex calculations or DOM updates here}, 300);window.addEventListener('scroll', handleScroll);
4. 記憶化
記憶化是一種優(yōu)化技術(shù),涉及緩存昂貴的函數(shù)調(diào)用的結(jié)果,并在再次出現(xiàn)相同輸入時返回緩存的結(jié)果。
這可以 避免冗余計算,顯著提高計算成本高昂的函數(shù)的性能,尤其是那些使用相同參數(shù)頻繁調(diào)用的函數(shù)。
● 用例
提高斐波那契數(shù)計算等遞歸函數(shù)的性能。如果沒有記憶化,每次調(diào)用斐波那契函數(shù)都會重復(fù)計算相同的值多次,從而導(dǎo)致指數(shù)時間復(fù)雜度。
const memoize = (fn) => {const cache = {};return (...args) => {const key = JSON.stringify(args);if (!cache[key]) {cache[key] = fn(...args);}return cache[key];};};const fibonacci = memoize((n) => {if (n <= 1) return n;return fibonacci(n - 1) + fibonacci(n - 2);});console.log(fibonacci(40)); // 102334155
5. 代理
代理對象允許您為另一個對象創(chuàng)建代理,該代理可以攔截和重新定義該對象的基本操作,例如屬性查找、賦值、枚舉、函數(shù)調(diào)用等。
這提供了一種向?qū)ο筇砑幼远x行為的強(qiáng)大方法。
● 用例
實現(xiàn)對對象屬性訪問和賦值的驗證和日志記錄。例如,您可以強(qiáng)制執(zhí)行類型約束并記錄訪問嘗試,從而提供更好的控制和調(diào)試功能。
const user = {name: 'John',age: 30};const handler = {get: (target, prop) => {console.log(`Getting ${prop}`);return target[prop];},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[prop] = value;return true;}};const proxyUser = new Proxy(user, handler);console.log(proxyUser.name); // Getting name, JohnproxyUser.age = 35; // Setting age to 35// proxyUser.age = '35'; // Throws TypeError
6. 生成器
生成器是可以退出并稍后重新進(jìn)入的函數(shù),在重新進(jìn)入之間保持其上下文和變量綁定。
它們對于實現(xiàn)迭代器和以同步方式處理異步任務(wù)非常有用。
● 用例
實現(xiàn)迭代器以進(jìn)行自定義對象遍歷。生成器提供了一種定義自定義迭代行為的簡單方法,使遍歷復(fù)雜數(shù)據(jù)結(jié)構(gòu)變得更簡單。
function* objectEntries(obj) {for (let key of Object.keys(obj)) {yield [key, obj[key]];}}const user = { name: 'John', age: 30, city: 'New York' };for (let [key, value] of objectEntries(user)) {console.log(`${key}: ${value}`);}// name: John// age: 30// city: New York
7. 充分利用控制臺
增強(qiáng)調(diào)試信息的可見性和組織性,使診斷和解決問題變得更加容易。正確使用控制臺方法可以通過提供清晰、有條理和詳細(xì)的日志來顯著改善調(diào)試過程。
● 用例
改進(jìn)用于調(diào)試復(fù)雜對象的日志記錄。console.table、console.group 和 console.time 等控制臺方法可以提供更結(jié)構(gòu)化和信息豐富的調(diào)試信息。
// Basic loggingconsole.log('Simple log');console.error('This is an error');console.warn('This is a warning');// Logging tabular dataconst users = [{ name: 'John', age: 30, city: 'New York' },{ name: 'Jane', age: 25, city: 'San Francisco' },];console.table(users);// Grouping logsconsole.group('User Details');console.log('User 1: John');console.log('User 2: Jane');console.groupEnd();// Timing code executionconsole.time('Timer');for (let i = 0; i < 1000000; i++) {// Some heavy computation}console.timeEnd('Timer');
8. 使用 structuredClone 進(jìn)行結(jié)構(gòu)化克隆
使用新的 structuredClone 方法深度克隆對象。
與傳統(tǒng)的淺層復(fù)制不同,結(jié)構(gòu)化克隆會創(chuàng)建對象的深層副本,確保嵌套對象也被復(fù)制。
此方法避免了 JSON.parse(JSON.stringify(obj)) 的局限性,它無法處理某些數(shù)據(jù)類型,如函數(shù)、未定義和循環(huán)引用。
● 用例
創(chuàng)建復(fù)雜對象的深層副本。當(dāng)需要復(fù)制對象以執(zhí)行不應(yīng)更改原始數(shù)據(jù)的操作時,這很有用。
const obj = {a: 1,b: { c: 2 },date: new Date(),arr: [1, 2, 3],nestedArr: [{ d: 4 }]};const clonedObj = structuredClone(obj);console.log(clonedObj);// { a: 1, b: { c: 2 }, date: 2023-06-08T00:00:00.000Z, arr: [1, 2, 3], nestedArr: [{ d: 4 }] }console.log(clonedObj === obj); // falseconsole.log(clonedObj.b === obj.b); // falseconsole.log(clonedObj.date === obj.date); // falseconsole.log(clonedObj.arr === obj.arr); // falseconsole.log(clonedObj.nestedArr[0] === obj.nestedArr[0]); // false
9. 自調(diào)用函數(shù)
自調(diào)用函數(shù),也稱為立即調(diào)用函數(shù)表達(dá)式 (IIFE),是在創(chuàng)建時自動執(zhí)行的函數(shù)。
它們對于封裝代碼以避免污染全局范圍很有用,這對于維護(hù)干凈和模塊化的代碼至關(guān)重要。
● 用例
封裝代碼以避免污染全局范圍。此技術(shù)在較舊的 JavaScript 環(huán)境中特別有用,在這些環(huán)境中,塊作用域(let 和 const)不可用,或者當(dāng)需要立即執(zhí)行初始化邏輯時。
(function() {const privateVar = 'This is private';console.log('Self-invoking function runs immediately');// Initialization code})();// Private variable can't be accessed from outside// console.log(privateVar); // ReferenceError: privateVar is not defined
10. 標(biāo)記模板文字
標(biāo)記模板文字允許你自定義模板文字的處理方式。
它們對于創(chuàng)建專用模板很有用,例如用于國際化、清理HTML或生成動態(tài)SQL查詢。
● 用例
清理HTML模板中的用戶輸入以防止XSS攻擊。此技術(shù)可確保用戶生成的內(nèi)容安全地插入DOM中,而不會執(zhí)行任何惡意腳本。
function sanitize(strings, ...values) {return strings.reduce((result, string, i) => {let value = values[i - 1];if (typeof value === 'string') {value = value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');}return result + value + string;});}const userInput = '<script>alert("xss")</script>';const message = sanitize`User input: ${userInput}`;console.log(message); // User input: <script>alert("xss")</script>
點擊名片回復(fù)『編程』
即可獲取1000+編程學(xué)習(xí)手冊
