/ / Tại sao bạn nên cẩn thận khi sử dụng các hàm mũi tên trong JavaScript

Tại sao bạn nên cẩn thận khi sử dụng các hàm mũi tên trong JavaScript

woman working on macbook pro 6

Cú pháp hàm mũi tên xuất hiện cùng với việc phát hành ECMAScript 2015, còn được gọi là ES6. Ngày nay, chức năng mũi tên đã trở thành tính năng yêu thích của nhiều lập trình viên JavaScript. Tình yêu dành cho các hàm mũi tên này là do cú pháp ngắn gọn và hành vi đơn giản của từ khóa “this”.


Nhưng chức năng mũi tên có một số nhược điểm. Tìm hiểu về sự khác biệt chính giữa hàm mũi tên và hàm thông thường và tìm hiểu lý do tại sao, trong hầu hết các trường hợp, tốt hơn hết là bạn nên sử dụng các hàm thông thường.


1. Bạn phải xác định chức năng mũi tên trước khi sử dụng nó

Bạn không thể nâng chức năng mũi tên. Các quy tắc nâng mặc định của JavaScript cho phép bạn gọi một hàm trước khi xác định nó, nhưng đó không phải là trường hợp của các hàm mũi tên. Nếu bạn có tệp JavaScript có chức năng, điều này có nghĩa là tất cả mã quan trọng sẽ nằm ở cuối tệp.

Hãy xem xét ví dụ mã JavaScript sau:

 const doubleNumbers = (numbers) { 
  numbers.map(n => n * 2)
}

const halveNumbers = (numbers) {
  numbers.map(n => n / 2)
}

const sumNumbers = (numbers) {
  numbers.reduce((sum, n) => {
    return sum + n;
  }, 0)
}

const numbers = [1, 20, 300, 700, 1500]
const doubled = doubleNumbers(numbers)
console.log(halveNumbers(doubled))
console.log(sumNumbers(numbers))

Trong khối mã ở trên, mã quan trọng nằm ở dưới cùng. Tất cả các chức năng của trình trợ giúp đều được xác định trước điểm thực thi. Việc phải tạo các hàm JavaScript của bạn ở đầu tệp có thể gây bất tiện vì bạn sẽ phải cuộn xuống để xem mã thực sự hoạt động.

Nếu bạn di chuyển các chức năng của trình trợ giúp xuống dưới cùng và mã thực tế lên trên cùng, bạn sẽ gặp lỗi tham chiếu. Bộ thực thi coi hàm là một biến. Vì vậy, bạn phải xác định nó trước khi truy cập hoặc gọi nó. Nhưng nếu bạn đã chuyển đổi tất cả các hàm mũi tên thành các hàm thông thường (với chức năng từ khóa), thì mã của bạn sẽ hoạt động tốt. Đồng thời, mã quan trọng vẫn ở trên cùng nơi bạn có thể xác định vị trí của nó.

Đây là một trong những vấn đề lớn nhất khi sử dụng hàm mũi tên. Họ không thể hiện bất kỳ hành vi lưu trữ. Nói cách khác, bạn phải xác định chúng trước vị trí thực tế mà bạn sẽ sử dụng chúng. Mặt khác, bạn có thể kéo các chức năng thông thường.

2. Chức năng mũi tên có thể gây nhầm lẫn cho một số người

Một lý do khác để sử dụng các hàm thông thường thay vì các hàm mũi tên là khả năng đọc. Các hàm thông thường dễ đọc hơn vì chúng sử dụng rõ ràng chức năng từ khóa. Từ khóa này xác định rằng mã được đề cập là một hàm.

Mặt khác, bạn gán các hàm mũi tên cho các biến. Là một người mới, điều này có thể khiến bạn nhầm lẫn khi nghĩ rằng mã là một biến chứ không phải là một hàm.

So sánh hai chức năng dưới đây:

 const halveNumbers = (numbers) => {
  return numbers.map(n => n / 2)
}

function halveNumbers(numbers) {
  return numbers.map(n => n / 2)
}

Thoạt nhìn, bạn có thể dễ dàng nhận ra rằng đoạn mã thứ hai là một hàm. Cú pháp làm rõ rằng mã là một chức năng. Tuy nhiên, điều đầu tiên là mơ hồ—bạn có thể không dễ dàng biết đó là một biến hay một hàm.

3. Bạn không thể sử dụng hàm mũi tên làm phương thức

Khi bạn sử dụng chức năng mũi tên, cái này từ khóa tương ứng với bất cứ thứ gì bên ngoài thứ mà chúng ta đang ở bên trong. Trong hầu hết các trường hợp, đó là đối tượng cửa sổ.

Xét đối tượng sau:

 const person = {
  firstName: "Kyle",
  lastName: "Cook",
  printName: () => {
    console.log(`${this.firstName}` `${this.lastName}` )
  }
}

person.printName()

Nếu bạn chạy mã này, bạn sẽ nhận thấy rằng trình duyệt in không xác định cho cả tên và họ. Vì chúng tôi đang sử dụng chức năng mũi tên, cái này từ khóa tương ứng với đối tượng cửa sổ. Ngoài ra, không có tên đầu tiên hoặc họ tài sản được xác định ở đó.

Để giải quyết vấn đề này, thay vào đó, bạn cần sử dụng một chức năng thông thường:

 const person = {
  firstName: "Kyle",
  lastName: "Cook",
  printName: function() {
    console.log(`${this.firstName}` `${this.lastName}` )
  }
}

person.printName()

Điều này sẽ làm việc tốt bởi vì cái này đề cập đến người sự vật. Nếu bạn sẽ thực hiện loại lập trình hướng đối tượng này nhiều, thì bạn cần đảm bảo rằng bạn đang sử dụng các hàm thông thường. Các chức năng mũi tên sẽ không hoạt động.

Khi nào nên sử dụng chức năng mũi tên

Sử dụng các chức năng mũi tên chủ yếu ở những nơi bạn cần một chức năng ẩn danh. Một ví dụ về tình huống như vậy là xử lý chức năng gọi lại. Tốt hơn là sử dụng hàm mũi tên khi viết hàm gọi lại vì cú pháp đơn giản hơn nhiều so với viết hàm đầy đủ.

So sánh hai cái này và quyết định cái nào đơn giản hơn:

 function halveNumbers(numbers) {
  return numbers.map(n => n / 2)
}

function halveNumbers(numbers) {
  return numbers.map(function(n) {
    return n / 2
  })
}

Cả hai trường hợp đều truyền hàm gọi lại cho phương thức map(). Nhưng cuộc gọi lại đầu tiên là một chức năng mũi tên trong khi cuộc gọi lại thứ hai là một chức năng đầy đủ. Bạn có thể thấy hàm đầu tiên chiếm ít dòng mã hơn hàm thứ hai như thế nào: ba so với năm.

Thời gian khác để sử dụng các hàm mũi tên là bất cứ khi nào bạn muốn xử lý một cú pháp “cái này” cụ thể. Đối tượng “this” sẽ thay đổi tùy thuộc vào việc bạn đang sử dụng hàm thông thường hay hàm mũi tên cho những thứ cụ thể.

Khối mã sau đăng ký hai trình xử lý sự kiện “nhấp chuột” trên đối tượng tài liệu. Phiên bản đầu tiên sử dụng chức năng thông thường làm hàm gọi lại, trong khi phiên bản thứ hai sử dụng chức năng mũi tên. Bên trong cả hai cuộc gọi lại, mã ghi lại đối tượng thực thi (cái này) và mục tiêu sự kiện:

 document.addEventListener("click", function(e) {
  console.log("FUNCTION", this, e.target)
})

document.addEventListener("click", (e) => {
  console.log("ARROW", this, e.target)
})

Nếu bạn chạy tập lệnh này, bạn sẽ nhận thấy rằng tham chiếu “này” là khác nhau cho cả hai. Đối với chức năng thông thường, thuộc tính này tham chiếu đến tài liệu, giống như thuộc tính e.mục tiêu tài sản. Nhưng đối với chức năng mũi tên, điều này tham chiếu đối tượng cửa sổ.

Khi bạn sử dụng một hàm thông thường làm hàm gọi lại, thì hàm này sẽ đề cập đến phần tử nơi chúng tôi kích hoạt sự kiện. Nhưng khi bạn sử dụng hàm mũi tên, thì từ khóa này sẽ mặc định cho đối tượng cửa sổ.

Tìm hiểu thêm về Hàm mũi tên so với Hàm thông thường

Có một số khác biệt tinh tế khác giữa chức năng thông thường và chức năng mũi tên. Nắm vững cả hai loại chức năng là nền tảng để thành thạo JavaScript. Tìm hiểu khi nào nên sử dụng cái này và khi nào nên sử dụng cái kia; sau đó bạn sẽ hiểu ý nghĩa của việc sử dụng hàm thông thường hoặc hàm mũi tên trong JavaScript của mình.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

/ / Tại sao bạn nên cẩn thận khi sử dụng các hàm mũi tên trong JavaScript

Tại sao bạn nên cẩn thận khi sử dụng các hàm mũi tên trong JavaScript

woman working on macbook pro 6

Cú pháp hàm mũi tên xuất hiện cùng với việc phát hành ECMAScript 2015, còn được gọi là ES6. Ngày nay, chức năng mũi tên đã trở thành tính năng yêu thích của nhiều lập trình viên JavaScript. Tình yêu dành cho các hàm mũi tên này là do cú pháp ngắn gọn và hành vi đơn giản của từ khóa “this”.


Nhưng chức năng mũi tên có một số nhược điểm. Tìm hiểu về sự khác biệt chính giữa hàm mũi tên và hàm thông thường và tìm hiểu lý do tại sao, trong hầu hết các trường hợp, tốt hơn hết là bạn nên sử dụng các hàm thông thường.


1. Bạn phải xác định chức năng mũi tên trước khi sử dụng nó

Bạn không thể nâng chức năng mũi tên. Các quy tắc nâng mặc định của JavaScript cho phép bạn gọi một hàm trước khi xác định nó, nhưng đó không phải là trường hợp của các hàm mũi tên. Nếu bạn có tệp JavaScript có chức năng, điều này có nghĩa là tất cả mã quan trọng sẽ nằm ở cuối tệp.

Hãy xem xét ví dụ mã JavaScript sau:

 const doubleNumbers = (numbers) { 
  numbers.map(n => n * 2)
}

const halveNumbers = (numbers) {
  numbers.map(n => n / 2)
}

const sumNumbers = (numbers) {
  numbers.reduce((sum, n) => {
    return sum + n;
  }, 0)
}

const numbers = [1, 20, 300, 700, 1500]
const doubled = doubleNumbers(numbers)
console.log(halveNumbers(doubled))
console.log(sumNumbers(numbers))

Trong khối mã ở trên, mã quan trọng nằm ở dưới cùng. Tất cả các chức năng của trình trợ giúp đều được xác định trước điểm thực thi. Việc phải tạo các hàm JavaScript của bạn ở đầu tệp có thể gây bất tiện vì bạn sẽ phải cuộn xuống để xem mã thực sự hoạt động.

Nếu bạn di chuyển các chức năng của trình trợ giúp xuống dưới cùng và mã thực tế lên trên cùng, bạn sẽ gặp lỗi tham chiếu. Bộ thực thi coi hàm là một biến. Vì vậy, bạn phải xác định nó trước khi truy cập hoặc gọi nó. Nhưng nếu bạn đã chuyển đổi tất cả các hàm mũi tên thành các hàm thông thường (với chức năng từ khóa), thì mã của bạn sẽ hoạt động tốt. Đồng thời, mã quan trọng vẫn ở trên cùng nơi bạn có thể xác định vị trí của nó.

Đây là một trong những vấn đề lớn nhất khi sử dụng hàm mũi tên. Họ không thể hiện bất kỳ hành vi lưu trữ. Nói cách khác, bạn phải xác định chúng trước vị trí thực tế mà bạn sẽ sử dụng chúng. Mặt khác, bạn có thể kéo các chức năng thông thường.

2. Chức năng mũi tên có thể gây nhầm lẫn cho một số người

Một lý do khác để sử dụng các hàm thông thường thay vì các hàm mũi tên là khả năng đọc. Các hàm thông thường dễ đọc hơn vì chúng sử dụng rõ ràng chức năng từ khóa. Từ khóa này xác định rằng mã được đề cập là một hàm.

Mặt khác, bạn gán các hàm mũi tên cho các biến. Là một người mới, điều này có thể khiến bạn nhầm lẫn khi nghĩ rằng mã là một biến chứ không phải là một hàm.

So sánh hai chức năng dưới đây:

 const halveNumbers = (numbers) => {
  return numbers.map(n => n / 2)
}

function halveNumbers(numbers) {
  return numbers.map(n => n / 2)
}

Thoạt nhìn, bạn có thể dễ dàng nhận ra rằng đoạn mã thứ hai là một hàm. Cú pháp làm rõ rằng mã là một chức năng. Tuy nhiên, điều đầu tiên là mơ hồ—bạn có thể không dễ dàng biết đó là một biến hay một hàm.

3. Bạn không thể sử dụng hàm mũi tên làm phương thức

Khi bạn sử dụng chức năng mũi tên, cái này từ khóa tương ứng với bất cứ thứ gì bên ngoài thứ mà chúng ta đang ở bên trong. Trong hầu hết các trường hợp, đó là đối tượng cửa sổ.

Xét đối tượng sau:

 const person = {
  firstName: "Kyle",
  lastName: "Cook",
  printName: () => {
    console.log(`${this.firstName}` `${this.lastName}` )
  }
}

person.printName()

Nếu bạn chạy mã này, bạn sẽ nhận thấy rằng trình duyệt in không xác định cho cả tên và họ. Vì chúng tôi đang sử dụng chức năng mũi tên, cái này từ khóa tương ứng với đối tượng cửa sổ. Ngoài ra, không có tên đầu tiên hoặc họ tài sản được xác định ở đó.

Để giải quyết vấn đề này, thay vào đó, bạn cần sử dụng một chức năng thông thường:

 const person = {
  firstName: "Kyle",
  lastName: "Cook",
  printName: function() {
    console.log(`${this.firstName}` `${this.lastName}` )
  }
}

person.printName()

Điều này sẽ làm việc tốt bởi vì cái này đề cập đến người sự vật. Nếu bạn sẽ thực hiện loại lập trình hướng đối tượng này nhiều, thì bạn cần đảm bảo rằng bạn đang sử dụng các hàm thông thường. Các chức năng mũi tên sẽ không hoạt động.

Khi nào nên sử dụng chức năng mũi tên

Sử dụng các chức năng mũi tên chủ yếu ở những nơi bạn cần một chức năng ẩn danh. Một ví dụ về tình huống như vậy là xử lý chức năng gọi lại. Tốt hơn là sử dụng hàm mũi tên khi viết hàm gọi lại vì cú pháp đơn giản hơn nhiều so với viết hàm đầy đủ.

So sánh hai cái này và quyết định cái nào đơn giản hơn:

 function halveNumbers(numbers) {
  return numbers.map(n => n / 2)
}

function halveNumbers(numbers) {
  return numbers.map(function(n) {
    return n / 2
  })
}

Cả hai trường hợp đều truyền hàm gọi lại cho phương thức map(). Nhưng cuộc gọi lại đầu tiên là một chức năng mũi tên trong khi cuộc gọi lại thứ hai là một chức năng đầy đủ. Bạn có thể thấy hàm đầu tiên chiếm ít dòng mã hơn hàm thứ hai như thế nào: ba so với năm.

Thời gian khác để sử dụng các hàm mũi tên là bất cứ khi nào bạn muốn xử lý một cú pháp “cái này” cụ thể. Đối tượng “this” sẽ thay đổi tùy thuộc vào việc bạn đang sử dụng hàm thông thường hay hàm mũi tên cho những thứ cụ thể.

Khối mã sau đăng ký hai trình xử lý sự kiện “nhấp chuột” trên đối tượng tài liệu. Phiên bản đầu tiên sử dụng chức năng thông thường làm hàm gọi lại, trong khi phiên bản thứ hai sử dụng chức năng mũi tên. Bên trong cả hai cuộc gọi lại, mã ghi lại đối tượng thực thi (cái này) và mục tiêu sự kiện:

 document.addEventListener("click", function(e) {
  console.log("FUNCTION", this, e.target)
})

document.addEventListener("click", (e) => {
  console.log("ARROW", this, e.target)
})

Nếu bạn chạy tập lệnh này, bạn sẽ nhận thấy rằng tham chiếu “này” là khác nhau cho cả hai. Đối với chức năng thông thường, thuộc tính này tham chiếu đến tài liệu, giống như thuộc tính e.mục tiêu tài sản. Nhưng đối với chức năng mũi tên, điều này tham chiếu đối tượng cửa sổ.

Khi bạn sử dụng một hàm thông thường làm hàm gọi lại, thì hàm này sẽ đề cập đến phần tử nơi chúng tôi kích hoạt sự kiện. Nhưng khi bạn sử dụng hàm mũi tên, thì từ khóa này sẽ mặc định cho đối tượng cửa sổ.

Tìm hiểu thêm về Hàm mũi tên so với Hàm thông thường

Có một số khác biệt tinh tế khác giữa chức năng thông thường và chức năng mũi tên. Nắm vững cả hai loại chức năng là nền tảng để thành thạo JavaScript. Tìm hiểu khi nào nên sử dụng cái này và khi nào nên sử dụng cái kia; sau đó bạn sẽ hiểu ý nghĩa của việc sử dụng hàm thông thường hoặc hàm mũi tên trong JavaScript của mình.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *