Blog#16: Điểm khác nhau giữa Regular Function vs Arrow Function (Hàm thông thường và hàm mũi tên) 😊 (Series: Bí kíp Javascript – PHẦN 13)

Mình là TUẤN hiện đang là một Full-stack Developer tại Tokyo 😉. Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé 😊. Bạn có thể khai báo các Functions của bạn theo nhiều cách. Sử dụng keyword function: // function declarationfunctiontest(msg){return`Hey ${msg}`;}// function expressionconsttest=function(msg){return`Hey ${msg}`;};

Mình là TUẤN hiện đang là một Full-stack Developer tại Tokyo 😉.
Nếu bạn thấy Blog này hay xin hãy cho mình một like và đăng ký để ủng hộ mình nhé 😊.

Bạn có thể khai báo các Functions của bạn theo nhiều cách.

Sử dụng keyword function:

// function declarationfunctiontest(msg){return`Hey ${msg}`;}// function expressionconsttest=function(msg){return`Hey ${msg}`;};

Bạn có thể gọi cả khai báobiểu thức hàm là Normal/Regular Function

Arrow function được giới thiệu trong ES6 và còn được gọi là arrow function.

constarrowFunction=(msg)=>{return`Hey $ {msg}`}

Như bạn thấy cả hai function hoạt động giống nhau trong ví dụ trên. Bây giờ câu hỏi đặt ra là tại sao chúng ta cần regular funcion hoặc arrow function.

Cùng thảo luận một số vấn đề bên dưới nhé 👇

1. Syntax – Cú pháp

2. Arguments binding – Ràng buộc đối số

3. this

4. eyword: new

5. Không có parameters được đặt tên trùng lặp

6. Function Hoisting

7. Method

————————————–

1️. Syntax – Cú pháp

Chúng ta có thể viết hàm regulararrow function theo cách này 😎

// ES5varadd=function(x, y){return x + y;};// ES6letadd=(x, y)=> x + y;

Implicit Return – Return ngầm định

Trong hàm thông thường, bạn phải sử dụng keyword return để trả về bất kỳ value nào. Nếu bạn không trả về bất kỳ thứ gì thì hàm sẽ trả về undefined.

functionregFunc(){return"Regular Function";}regFunc();// Regular FunctionfunctionregFunc(){
  console.log("Regular Function");}regFunc();// Regular Function// undefined

Các arrow function hoạt động theo cách tương tự khi trả về giá trị.

Nếu arrow function chứa một biểu thức, bạn có thể bỏ qua dấu ngoặc nhọn và khi đó biểu thức sẽ được trả về implicitly returned.

{}không bắt buộc nếu nó chỉ có một dòng tuyên bố

constaddOne=(number)=> number +1;addOne(10);

()không bắt buộc nếu bạn chỉ có một đối số

let add = (x) => x + x;

Nếu không có đối số

let arrowFunc = _ => console.log("Arrow Function");

2️. Arguments binding – Đối số ràng buộc

Trong hàm thông thường, các keyword arguments có thể được sử dụng để truy cập các đối số được truyền cho hàm.

Thí dụ:

functionregularFunction(a, b){
  console.log(arguments);}regularFunction(1,2);// Arguments[1,2]

Các arrow function không có ràng buộc đối số.

constarrowFunction=(a, b)=>{
  console.log(arguments);};arrowFunction(1,2);//ReferenceError: arguments is not defined

Tuy nhiên, nếu bạn muốn truy cập các đối số trong một arrow function, bạn có thể sử dụng toán tử rest:

vararrowFunction=(...args)=>{
  console.log(...args);};arrowFunction(1,2);// 1 2

3️. this

Trong hàm thông thường, this thay đổi theo cách hàm đó được gọi.

  • Simple Invocation:this bằng đối tượng toàn cục hoặc có thể không xác định nếu bạn đang sử dụng chế độ strict mode.
  • Method Invocation:this bằng đối tượng sở hữu hàm.
  • Indirect Invocation:this bằng đối số đầu tiên.
  • Constructor Invocation:this bằng instance mới được tạo.
// 1️⃣ Simple InvocationfunctionsimpleInvocation(){
  console.log(this);}simpleInvocation();// Window Object// 2️⃣ Method Invocationconst methodInvocation ={method(){
    console.log(this);},};
methodInvocation.method();// logs methodInvocation object// 3️⃣ Indirect Invocationconst context ={ aVal:"A", bVal:"B"};functionindirectInvocation(){
  console.log(this);}indirectInvocation.call(context);// logs { aVal: 'A' }indirectInvocation.apply(context);// logs { bVal: 'A' }// 4️⃣ Constructor InvocationfunctionconstructorInvocation(){
  console.log(this);}newconstructorInvocation();// logs an instance of constructorInvocation

Các arrow function không có this riêng và chúng không xác định lại value của this bên trong hàm.

this bên trong một arrow function luôn đề cập đến this từ contexts bên ngoài.

var name ="Suprabha"let newObject ={
    name :"supi",arrowFunc:()=>{
        console.log(this.name);},regularFunc(){
        console.log(this.name);}}
newObject.arrowFunc();// Suprabha
newObject.regularFunc();// supi

4️. new

Các hàm thông thường có thể sử dụng constructor, chúng có thể được gọi bằng cách sử dụng keyword new.

functionadd(x, y){
  console.log(x + y);}let sum =newadd(2,3);// 5

Tuy nhiên, các arrow function không bao giờ có thể được sử dụng như các hàm khởi tạo. Do đó, chúng không bao giờ có thể được gọi với keyword new

letadd=(x, y)=> console.log(x + y);const sum =newadd(2,4);// TypeError: add is not a constructor

5️. paramaters không được đặt tên trùng lặp

Trong function bình thường, chúng ta có thể làm điều này:

// ✅ will workfunctionadd(a, a){}// ❌ will not work("use strict");functionadd(a, a){}// Uncaught SyntaxError: Duplicate parameter name not allowed in this context

Các arrow function không bao giờ được có các tham số được đặt tên trùng lặp, cho dù ở chế độ strict mode hay non-strict mode.

constarrowFunc=(a, a)=>{};// Uncaught SyntaxError: Duplicate parameter name not allowed in this context

6️. Function Hoisting

Trong function thông thường, function được hoisting lên ở đầu.

normalFunc();functionnormalFunc(){return"Normal Function";}// "Normal Function"

Trong arrow function, hàm được hoisting vào nơi bạn khai báo nó. Vì vậy, nếu bạn gọi hàm trước khi khai báo, bạn sẽ nhận được referenceError.

arrowFunc();constarrowFunc=()=>{return"Arrow Function";};// ReferenceError: Cannot access 'arrowFunc' before initializati

7️. Methods

Bạn có thể xác định các hàm trong lớp bằng cách sử dụng hàm thông thường.

classFullName{constructor(name){this.name = name;}result(){
    console.log(this.name);}}let name =newFullName("Suprabha");
console.log(name);// FullName {name: "Suprabha"}

Bạn cũng cần áp dụng callback.

setTimeout(name.result,2000);// after 1 second logs ""

Nhưng nếu bạn ràng buộc this

setTimeout(name.result.bind(name),2000);// Suprabha

Bằng ví dụ trên, bạn có thể thấy rằng bạn phải liên kết contexts this với context của chúng.

Trong arrow function, bạn không cần phải ràng buộc với context.

classFullName{constructor(name){this.name = name;}result=()=>{
    console.log(this.name);};}let name =newFullName("Suprabha");setTimeout(name.result,2000);// Suprabha

Khi nào không sử dụng arrow function 👩🏻‍💻

Object

let dog ={
  count:3,jumps:()=>{this.count++;},};

Khi bạn gọi dog.jumps, số đếm không tăng lên. Đó là bởi vì this không bị ràng buộc với bất cứ điều gì, và sẽ kế thừa value của this từ phạm vi cha của nó.

Tham khảo 🧐

Tóm tắt

Trong hàm thông thường, this value là động, Trong arrow function, this value bằng với value của hàm ngoài.

Trong hàm thông thường, các đối số sẽ cung cấp cho bạn danh sách tham số arguments được truyền vào hàm. argument của arrow function không được xác định.

Trong hàm thông thường, bạn luôn phải trả về bất kỳ value nào, nhưng trong arrow function, bạn có thể bỏ qua keyword return và có thể viết single line.

Trong mũi tên, các tham số của hàm phải là duy nhất.

Vấn đề Hoisting trong arrow function vì hàm không được gọi trước khi khởi tạo.

Như mọi khi, mình hy vọng bạn thích bài viết này và biết thêm được điều gì đó mới.

Cảm ơn và hẹn gặp lại các bạn trong những bài viết tiếp theo! 😍

Nếu bạn thấy thích blog của mình thì nhấn theo dõi để ủng hộ mình nhé. Thank you.😉

Ref

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ