Sự khác nhau giữa Regular và Arrow Functions trong JavaScript

Nội dung bài viết

Regular và Arrow Functions thường xuyên được sử dụng trong mỗi module của bất kỳ developer nào. Nhưng có khi nào devjs thật sự để ý rằng giữa Regular function và Arrow Functions khác nhau những gì và tại sao phải sử dụng 2 loại function như vậy không?


Thật sự mà nói trong quá trình code của chúng ta, đã có khi bạn đã từng bị đi vào những rắc rối tưởng chừng như đơn giản như sử dụng "this" chẳng hạn, nhưng nếu bạn notes lại cho mọi người thì điều đó thật sự là một việc làm ý nghĩa hơn nữa. Chính vì vậy, cho dù những kiến thức đơn giản hay phức tạp nếu bạn có thể ghi lại thì quả thật là một điều tuyệt vời.


Trong bài post này tipjs đã tham khảo một số bài viết nói về sự khác biệt giữa Regular và Arrow Functions, và sau đây là những điểm khác biệt chủ yếu. Nhưng đầu tiên chúng ta hãy hiểu thế nào là Regular và Arrow function.


Regular function là gì?


Regular function là việc khai báo một hàm thông thường. Thông thường ở đây có nghĩa là bạn khai báo hàm một lần và sau đó gọi nó ở nhiều nơi khác nhau. Đây là một dạng Regular function

function sum(a, b) {
  return a + b;
}
sum(5, 6);           // => 11
([3, 7]).reduce(sum) // => 10

Arrow function là gì?


Arrow function được tips JavaScript nói rất nhiều trong nhiều bài viết, nó được giới thiệu ở ES6, giúp code chúng ta ngắn gọn và xúc tích hơn nhiều, bạn có thể đọc những bài trước, cụ thể ES6 Arrow Functions Cheatsheet. Ở đó bạn sẽ không những hiểu Arrow function là gì? Mà còn giúp bạn hiểu được syntax và khi nào sử dụng Arrow function ở hoàn cảnh nào.


Còn bây giờ chúng ta sẽ đi tìm hiểu sự khác biệt giữa hai loại trên.


Sự khác biệt giữa Regular và Arrow Functions


Bằng cách sử dụng function thì những developers sẽ dễ dàng tạo code trong những block của mình. JavaScript cũng vậy, cung cấp cho ta nhiều cách kể cả ES5 hay ES6 đều cung cấp những chỉ khác về cú pháp - syntax.


Syntax of regular vs arrow function


# Không sử dụng parameter

/***** ES5 Regular Function  *****/

let prtLangReg = function () {
console.log("JavaScript");
}
prtLangReg();

/***** ES6 Arrow Function  *****/

let prtLangArrow = _ => {console.log("JavaScript");}
prtLangArrow();

# Sử dụng một parameter

/***** ES5 Regular Function  *****/
let prtLangReg = function (language) {
console.log(language);
}
prtLangReg("JavaScript");

/***** ES6 Arrow Function  *****/
let prtLangArrow = (language) => { console.log(language); }
prtLangArrow("JavaScript");

# sử dụng nhiều parameters

/***** ES5 Regular Function  *****/
let prtLangReg = function (id, language) {
console.log(id + ".) " + language);
}
prtLangReg(1, "JavaScript");

/***** ES6 Arrow Function  *****/
let prtLangArrow = (id, language) => { console.log(id + ".) " + language); }
prtLangArrow(1, "JavaScript");

Ta có thể nhìn tổng quan và có thể thấy ở arrow function thì trông có vẻ gọn gàng và thông minh hơn hẳn. Điều đó phải đúng vì thằng ES6 đi sau mà.


Khác nhau về scope giữa regular và arrow function


Nói đến đây thì phải nói đến sự khác biệt giữa regular và arrow function đó chính là "this". Một keyword rất quan trọng, bởi nó chứa đựng reference. Reference có thể là một window object, hay bất kỳ một một object nào tuỳ thuộc vào điều kiện lập trình.


let language = {
name: "JavaScript",
prtLangReg: function (id, language) {
console.log(this);
},
prtLangArrow: (id, language) => { console.log(this); }
}
language.prtLangReg();  // ES5 Function Call
language.prtLangArrow(); // ES6 Function Call

Ouput:

{
name:"JavaScript",
prtLangReg:f prtLangReg {...},
prtLangArrow:f prtLangArrow {...}
}

:[object Window]

Khi copy/paste chạy ví dụ này thì các bạn sẽ nhận được hai kết quả khác nhau. Với việc sử dụng Regular function thì "this" sẽ là reference hiện tại của JavaScript Object, nhưng ngược lại thì arrow function thì "this" lúc này đó là một global window object. Vì sao, bởi vì khác nhau chính là "scope", arrow function lấy scope từ the parent đó chính là window object.


Khác nhau về Arguments binding trong ES5 regular và ES6 arrow functions


Nếu như ES6 trong JavaScript cung cấp cho chúng ta arguments Object để pass vào function, nhưng đối với arrow function thì nói không với argument.

let language = {
name: "JavaScript",
prtLangReg: function () {
console.log(arguments); // 1, JavaScript
},
prtLangArrow: () => {
console.log(arguments); //argument is not defined
}
}
language.prtLangReg(1, "JavaScript");
language.prtLangArrow(1, "JavaScript");

Sau khi run ví dụ trên thì chúng ta nhận được gì???

{
0:1,
1:"JavaScript"
}

error: Uncaught ReferenceError: arguments is not defined

Arrow function cho ta một kết quả đáng buồn: error: Uncaught ReferenceError: arguments is not defined


Khi nào sử dụng ES5 regular và ES6 arrow functions


Qua những ví dụ để phân biệt thì bạn có nhận ra rằng, "ủa khi nào sử dụng loại nào đây?". Câu hỏi hay đấy, để tôi nói thêm về điều này một chút. Arrow function làm việc rất tốt trong callbacks function như setTimeout, Map, Reduce ... Nhưng Regular function chỉ làm việc tốt nhất với Objects. Điều này có nghĩa là gì, đó chính là đừng sử dụng Arrow function khi làm việc với object, hãy sử dụng với những Higher-Order Function. Nhưng để hiểu thêm về lợi ích sử dụng arrow function thì bạn nên đọc thêm về bài viết "ES6 Arrow Functions Cheatsheet"


Reference:

Có thể bạn đã bị miss