[Javascript Front End] - 3 tính năng javascript thú vị bạn chưa hề biết?

Xin chào các devjs. Dạo gần đây tôi đã phát hiện ra một số tính năng mà tôi chưa chia sẻ cho các bạn trong quá trình viết bài về tips and tricks trong javascript bao gồm (Labeled Statement, parseURL, IntersectionObserver). Có thể những tính năng trong bài viết này sẽ là một trong những ý tưởng tốt để giải quyết một số vấn đề của các bạn. 

Và trong bài viết này tôi sẽ giới thiệu cho các bạn 3 tính năng javascript giúp bạn nhiều ý tưởng hơn khi giải quyết một vấn đề nào đó.

1 - parseURL

Trước đây tôi đã từng giới thiệu một số cách parse một url để get những properties trên url đó. Và gần đây tôi nhận thấy có một cách hay hơn nhiều. Nghĩa là, việc tạo a sẽ gán URL được phân tích cú pháp cho thuộc tính href của a và sau đó chúng ta có thể dễ dàng lấy nội dung. 

Code như thế này:

function parseURL(url) {
    var a =  document.createElement('a');
    a.href = url;
    return {
        host: a.hostname,
        port: a.port,
        query: a.search,
        params: (function(){
            var ret = {},
                seg = a.search.replace(/^\?/,'').split('&'),
                len = seg.length, i = 0, s;
            for (;i<len;i++) {
                if (!seg[i]) { continue; }
                s = seg[i].split('=');
                ret[s[0]] = s[1];
            }
            return ret;
        })(),
        hash: a.hash.replace('#','')
    };
}

Sử dụng:

 
console.log(parseURL('https://marketplace.visualstudio.com/items?itemName=Equinusocio.vsc-material-theme&itemLast=abc#hashtag1'))

ouput:

{
  "host":"marketplace.visualstudio.com",
  "port":"",
  "query":"?itemName=Equinusocio.vsc-material-theme&itemLast=abc",
  "params":{
    "itemName":"Equinusocio.vsc-material-theme",
    "itemLast":"abc"
  },
  "hash":"hashtag1"
}

2 - Sử dụng lable trong loop javascript.

Labeled Statement Bạn có thể sử dụng label trong Javascript để nhảy tới từng kết quả của label giống như câu lệnh goto trong một số ngôn ngữ khác. Label dạng này chỉ có thể được sử dụng với câu lệnh break và continue trong vòng lặp. Và thường thì lable ít devjs nào sử dụng vì nó hiếm khi gặp. 

Nhưng đây là một keyword rất quan trọng trong việc xử lý tính toán nặng các data của các chuyên gia phát triển thuật toán. Ví dụ sau đây để hiểu thêm về Labeled Statement. 

#Case 1: Không sử dụng lable

for (let i = 0; i < 3; i++) { 
   for (let j = 0; j < 3; j++) {
      if (i === j) {
         continue;
      }
      console.log(`i = ${i}, j = ${j}`);
   }
}
// Ouput 6 results
i = 0, j = 1
i = 0, j = 2
i = 1, j = 0
i = 1, j = 2
i = 2, j = 0
i = 2, j = 1

#Case 2: Sử dụng lable

firstLoop: 
for (let i = 0; i < 3; i++) { 
   for (let j = 0; j < 3; j++) {
      if (i === j) {
         continue firstLoop; 
         // break firstLoop;
      }
      console.log(`i = ${i}, j = ${j}`);
   }
}
// Ouput 3 results 
i = 1, j = 0
i = 2, j = 0
i = 2, j = 1

Đến đây có bạn nào không hiểu về sử dụng lable. Để mình giải thích hai trường hợp trên cho các bạn hiểu rõ luôn.

 Case 1 không có lable thì đương nhiên không cần giải thích rồi. Mình sẽ giải thích case 2 với lable. Ở case2 thì chúng ta có 2 loop. Việc đặt firstLoop: (chính là lable) là đại diện cho loop 1 với var i. Loop 2 với j thì không có lable. Ở loop đầu tiên thì chạy từ 0, 1, 2. Tương ứng với i = 0 thì j lần lượt chạy 0, 1, 2. Tương tự với i = 1 và = 2 thì j cũng lần lượt chạy 0, 1, 2 như case1. Nhưng giờ có lable thì ta có thể nhảy về loop1 khi i === j. Cụ thể khi chạy vòng đầu tiên thì i = 0 và j = 0 do đó nó sẽ đi vào

if (i === j) {
    continue firstLoop; 
    // break firstLoop;
}

Do

continue firstLoop; 

nên nó sẽ tiếp tục với loop đầu tiên là i = 1. Chứ không phải tiếp tục với loop với biến j. Cứ như thế thì results sẽ

// Ouput 3 results 
i = 1, j = 0
i = 2, j = 0
i = 2, j = 1

Điều này giúp các developer hạn chế việc xử lý vòng lặp một cách hiệu quả hơn. Những ai chưa hiểu thì có thể commented FB, mình sec giải thích hơn. 

3 - IntersectionObserver là gì?

IntersectionObserver cụm từ này chắc nhiều bạn biết hơn 2 khái niệm trên. Nó được dùng nhiều trong các lib lazyload. IntersectionObserver có thể được sử dụng để theo dõi xem một phần tử đã đi vào vùng hiển thị của thiết bị hay không mà không cần phải tính toán thường xuyên và phức tạp để đưa ra quyết định này.

Chúng ta sẽ đi một ví dụ cụ thể. 

check demo : https://googlechrome.github.io/samples/intersectionobserver/

/* global IntersectionObserver */
var scroller = document.querySelector('#scroller');
var sentinel = document.querySelector('#sentinel');
var counter = 1;

function loadItems(n) {
  for (var i = 0; i < n; i++) {
    var newItem = document.createElement('div');
    newItem.classList.add('item');
    newItem.textContent = 'Item ' + counter++;
    scroller.appendChild(newItem);
  }
}

var intersectionObserver = new IntersectionObserver(entries => {
  // If intersectionRatio is 0, the sentinel is out of view
  // and we do not need to do anything.
  if (entries[0].intersectionRatio <= 0) {
    return;
  }
  loadItems(10);
  // appendChild will move the existing element, so there is no need to
  // remove it first.
  scroller.appendChild(sentinel);
  loadItems(5);
  ChromeSamples.setStatus('Loaded up to item ' + counter);
});
intersectionObserver.observe(sentinel);

Các bạn check ví dụ trên để hiểu hơn về IntersectionObserver. Khá hay đó. 

Xong rồi, một bài viết đơn giản nhưng để lại nhiều điều sâu sắc phải không? Sẽ có thể các bạn chưa cần những tips này nên sẽ mỉm cười cho qua. Nhưng các bạn đâu biết rằng một ngày nào đó khi lớn dần bạn sẽ quay lại bài viết này đấy. 

Happy coding   ! Chúc một ngày vui vẻ và tràn đầy năng lượng.