0

20 Thủ thuật JavaScript nâng cao dành cho các lập trình viên

Dù bạn là một lập trình viên dày dặn kinh nghiệm muốn trau dồi kỹ năng hay một người đam mê muốn tìm hiểu sâu hơn về những tinh hoa của JavaScript, bài viết này sẽ cung cấp thêm các kiến thức mở rộng cho bạn.

Hãy cùng khám phá 20 thủ thuật JavaScript nâng cao, không chỉ giúp bạn nâng cao kỹ năng lập trình mà còn mang đến những trải nghiệm thú vị khi tìm ra những cách tối ưu mã nguồn đầy sáng tạo!

1. Phép gán phân rã (Destructuring Assignment)

Phép gán phân rã là một tính năng mạnh mẽ cho phép bạn trích xuất giá trị từ mảng hoặc thuộc tính từ đối tượng vào các biến riêng biệt. Điều này giúp mã của bạn trở nên rõ ràng và gọn gàng hơn.

const [first, second] = [10, 20];
const { name, age } = { name: 'Alice', age: 30 };

2. Tham số mặc định (Default Parameters)

Tham số mặc định cho phép bạn thiết lập giá trị mặc định cho các tham số của hàm, giúp hàm linh hoạt hơn và dễ sử dụng hơn.

function greet(name = 'Guest') {
  console.log(`Hello, ${name}!`);
}
greet(); // Output: Hello, Guest!

3. Template Literals

Template literals cung cấp một cách để nhúng biểu thức vào trong chuỗi, giúp việc nội suy chuỗi trở nên dễ dàng hơn.

const name = 'Bob';
console.log(`Hello, ${name}!`);

4. Hàm mũi tên (Arrow Functions)

Hàm mũi tên cung cấp cú pháp ngắn gọn để viết biểu thức hàm và tự động ràng buộc giá trị this với ngữ cảnh xung quanh.

const add = (a, b) => a + b;

5. Toán tử Spread và Rest

Toán tử spread (...) cho phép bạn mở rộng một iterable (như mảng) thành các phần tử riêng lẻ, trong khi toán tử rest thu thập nhiều phần tử thành một mảng.

const numbers = [1, 2, 3];
const newNumbers = [...numbers, 4, 5];

function sum(...args) {
  return args.reduce((acc, val) => acc + val, 0);
}

6. Promises và Async/Await

Promises và cú pháp async/await giúp việc viết và hiểu code bất đồng bộ trở nên dễ dàng hơn.

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Error fetching data:', error);
  }
}

7. Optional Chaining (Chuỗi tùy chọn)

Optional chaining (?.) cho phép bạn truy cập an toàn vào các thuộc tính lồng nhau mà không cần kiểm tra từng cấp một cách tường minh.

const user = { name: 'Alice', address: { city: 'Wonderland' } };
const city = user?.address?.city;

8. Nullish Coalescing (Toán tử hợp nhất Null)

Toán tử nullish coalescing (??) cung cấp giá trị mặc định khi làm việc với null hoặc undefined.

const value = null ?? 'default';
console.log(value); // Output: default

9. Import Động (Dynamic Imports)

Import động cho phép bạn tải các mô-đun khi cần, giúp cải thiện hiệu suất bằng cách phân tách mã nguồn.

import('./module.js').then(module => {
  module.doSomething();
});

10. Proxy Objects

Proxy cho phép bạn tạo các đối tượng với hành vi tùy chỉnh cho các thao tác cơ bản (ví dụ: tra cứu thuộc tính, gán giá trị).

const handler = {
  get: (obj, prop) => {
    if (prop in obj) {
      return obj[prop];
    } else {
      return 'Property not found';
    }
  }
};

const proxy = new Proxy({ name: 'Alice' }, handler);
console.log(proxy.name); // Output: Alice
console.log(proxy.age);  // Output: Property not found

11. Memoization

Memoization là một kỹ thuật tối ưu hóa các hàm tính toán tốn kém bằng cách lưu trữ kết quả của chúng vào bộ nhớ cache.

function memoize(fn) {
  const cache = {};
  return function (...args) {
    const key = JSON.stringify(args);
    if (cache[key]) {
      return cache[key];
    } else {
      const result = fn(...args);
      cache[key] = result;
      return result;
    }
  };
}

12. Currying

Currying là một kỹ thuật lập trình hàm, trong đó một hàm với nhiều tham số được chuyển đổi thành một chuỗi các hàm đơn (unary functions).

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function (...args2) {
        return curried.apply(this, args.concat(args2));
      };
    }
  };
}

13. Hàm cấp cao (Higher-Order Functions)

Hàm cấp cao là những hàm nhận các hàm khác làm tham số hoặc trả về các hàm như là kết quả.

function higherOrder(fn) {
  return function (...args) {
    console.log('Before function call');
    const result = fn(...args);
    console.log('After function call');
    return result;
  };
}

14. Ủy quyền sự kiện (Event Delegation)

Ủy quyền sự kiện là một kỹ thuật xử lý sự kiện một cách hiệu quả bằng cách thêm một trình nghe sự kiện duy nhất vào phần tử cha.

document.querySelector('#parent').addEventListener('click', function (event) {
  if (event.target.tagName === 'BUTTON') {
    console.log('Button clicked:', event.target.textContent);
  }
});

15. Debouncing và Throttling

Debouncing và throttling là các kỹ thuật để kiểm soát tốc độ gọi hàm, hữu ích trong việc tối ưu hiệu suất cho các tình huống như sự kiện cuộn trang (scroll) hoặc thay đổi đầu vào (input).

function debounce(fn, delay) {
  let timeout;
  return function (...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => fn(...args), delay);
  };
}

function throttle(fn, limit) {
  let inThrottle;
  return function (...args) {
    if (!inThrottle) {
      fn(...args);
      inThrottle = true;
      setTimeout(() => (inThrottle = false), limit);
    }
  };
}

16. Custom Hooks trong React

Custom hooks trong React cho phép bạn đóng gói và tái sử dụng logic có trạng thái giữa các component.

function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = React.useState(() => {
    const item = window.localStorage.getItem(key);
    return item ? JSON.parse(item) : initialValue;
  });

  const setValue = value => {
    setStoredValue(value);
    window.localStorage.setItem(key, JSON.stringify(value));
  };

  return [storedValue, setValue];
}

17. Web Workers

Web Workers cho phép bạn chạy các script trong các luồng nền, giúp giao diện người dùng luôn phản hồi mượt mà.

const worker = new Worker('worker.js');
worker.postMessage('Hello, Worker!');
worker.onmessage = function (event) {
  console.log('Message from worker:', event.data);
};

18. Service Workers

Service Workers hoạt động như các proxy mạng, cho phép bạn tạo trải nghiệm ngoại tuyến hiệu quả và cải thiện hiệu suất.

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js').then(function (registration) {
    console.log('Service Worker registered with scope:', registration.scope);
  });
}

19. Intersection Observer API

Intersection Observer API cung cấp một cách để quan sát một cách bất đồng bộ sự thay đổi trong việc giao nhau giữa một phần tử mục tiêu và một phần tử tổ tiên hoặc vùng nhìn của tài liệu cấp cao nhất.

const observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('Element is in view:', entry.target);
    }
  });
});

observer.observe(document.querySelector('#target'));

20. Các phần tử tùy chỉnh và Shadow DOM

Các phần tử tùy chỉnh và Shadow DOM cho phép bạn tạo các component có thể tái sử dụng với kiểu dáng và hành vi được đóng gói riêng biệt.

class MyElement extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });
    shadow.innerHTML = `<style>:host { color: blue; }</style><p>Hello, World!</p>`;
  }
}

customElements.define('my-element', MyElement);

Hy vọng các thủ thuật này sẽ giúp ích cho các bạn trong quá trình lập trình


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.