Hướng dẫn function expression in javascript - biểu thức hàm trong javascript

Hướng dẫn function expression in javascript - biểu thức hàm trong javascript

Đã đăng vào thg 5 9, 2020 4:35 CH 3 phút đọc 3 phút đọc

// Function Declaration
function test(val){
    return val=== true;
}
 
// Function Expression
var isTest = function(val){
    return val === true;
}

Câu hỏi đặt ra là: chúng khác nhau chỗ nào?

  • Sự khác nhau đó là: function declaration có thể được lôi cổ gọi dùng bất cứ khi nào, bất cứ chỗ nào bởi bộ phân tích (interpreter) của trình duyệt. JavaScript biết sự có mặt của nó và parse nó trước khi chương trình JavaScript của chúng ta thực thi. Nói một cách khác (trừu tượng hơn) đó là JavaScript đưa các function loại này lên trên top của scope hiện tại.
myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}

Ở ví dụ trên chúng ta thấy hàm test() được gọi trước khi nó được khai báo. Tuy nhiên, chúng ta cũng có thể viết dạng như sau cũng được:

function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();

Còn function expression thì sao? Nó không được JavaScript đánh giá cho đến khi nó được gán vào biến. Hơi trừu tượng một tí, chúng ta làm cái ví dụ cho dễ hiểu

// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}

Nếu các bạn chạy đoạn mã trên thì sẽ báo lỗi vì expression được gọi trước khi nó được khai báo. Để chạy được, chúng ta phải viết lại như sau:

var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();

=> function declaration thì có thể gọi trước khi khai báo hoặc sau khi khai báo đều được, còn function expression thì phải có trình tự.

Function Declaration

  • khi bạn tạo ra một function có tên, đó gọi là function declaration
function handleClick() {
        console.log("clicked")
    }

Function Expression

const handleClick = function() {
        console.log("clicked")
    }
  • Hoặc sử dụng cú pháp es6 tạo ra một function anonymous (khai báo một function nhưng không dùng từ khóa function) cũng là function expression.
 const handleClick = () => {
        console.log('clicked')
    }
  • Bản chất:

    • Còn về bản chất function declaration và function expression khác nhau ở vùng scope ảnh hưởng. Với function declaration, tên của function sẽ hiện hữu ở scope của nó và scope cha của nó (Nơi nó được tạo ra), còn với function expression, tên của function (Nếu có) sẽ chỉ hiện hưũ ở scope của nó, và nó sẽ không tồn tại ngoài scope cha. Một điều quan trọng nữa, function expression sẽ không được hoisting như function bình thường.
// Chạy ngon
console.log(foo());
function foo() {};

// Lỗi
console.log(foo());
var a = function foo() {};

Hoisting

  • Khái niệm hoisting biểu thị function hay biến có thể được "gọi" ngay từ dòng code đầu tiên, trước khi chúng được khai báo.
  • Function Declaration có thuộc tính hoisting còn Function Expression thì không, điều này dễ dàng được biểu thị qua hai ví dụ sau: Đoạn code dưới đây sẽ thực thi bình thường khi dùng Function Declaration
handleStuff()

function handleStuff() {
    // do stuff
}

Đối với Function Expression thì sẽ báo lỗi

myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
0

Hoàn cảnh sử dụng

  • Qua hai phần trên, ta có thể thấy Function Declaration và Function Expression chủ yếu khác nhau bởi thuộc tính Hoisting và Function Declartion có vẻ như mạnh mẽ hơn vì phạm vi sử dụng, tuy nhiên trong thực tế chúng ta chỉ nên cân nhắc scope để sử dụng đúng Function Declaration, nhằm tránh việc có quá nhiều function không cần thiết trong global scope.

Tổng kết

  • Chúng ta sử dụng function declartion khi muốn tạo ra function để sử dụng ở bất cứ đâu trong toàn bộ mã code và sử dụng function expression khi function bị giới hạn vùng sử dụng, giúp global scope nhẹ và sạch hơn.

All rights reserved

Trong bài viết trước, mình đã tìm hiểu về hàm trong JavaScript. Cách khai báo hàm đó gọi là "function declaration". Bài viết này mình sẽ tìm hiểu về một khái niệm khác gọi là "function expression" hay dịch ra là "biểu thức hàm".

Function expression hiểu đơn giản là hàm được định nghĩa trong một biểu thức, ví dụ:

myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
1

Có thể hiểu là mình khởi tạo một hàm, rồi gán hàm đó cho biến

function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
4 giống như bất kỳ loại giá trị nào khác (number, string, boolean,...). Bạn có thể in ra giá trị biến
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
4:

myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
2

Kết quả hiển thị ra là một string biểu diễn hàm.

Chú ý: trong câu lệnh

function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
6 trên mình viết là
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
4 mà không có cặp dấu ngoặc đơn
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
8. Vì nếu có cặp dấu
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
8 thì đó nghĩa là gọi hàm.
: trong câu lệnh
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
6 trên mình viết là
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
4 mà không có cặp dấu ngoặc đơn
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
8. Vì nếu có cặp dấu
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
8 thì đó nghĩa là gọi hàm.

myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
3

Kết quả là function expression với

function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
4 được gọi, nên dòng chữ Hello from completejavascript.com được in ra.Hello from completejavascript.com được in ra.

Sau đó là dòng

// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
1 - vì biểu thức hàm
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
4 không có
// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
3 giá trị nào cả.

Đặc điểm của function expression

Vì biểu thức hàm cũng là một giá trị, nên bạn hoàn toàn có thể gán nó cho một biến khác, ví dụ:

myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
4

Khi đó, bạn gọi

// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
4 cũng giống như gọi
// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
5.

📝 Không chỉ function expression mà function declaration cũng là một giá trị.function expressionfunction declaration cũng là một giá trị.

Ví dụ:

myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
5

Hàm callback

Vì bản chất hàm là một giá trị, nên bạn có thể truyền hàm vào một hàm khác.

Ví dụ mình cần viết một hàm

// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
6 với ba tham số:

  • // Báo lỗi nè!
    expression();
    var expression = function (){
        alert(“Gọi tui là lỗi nha mấy chú”);
    }
    
    7: là một string, biểu thị câu hỏi.
  • // Báo lỗi nè!
    expression();
    var expression = function (){
        alert(“Gọi tui là lỗi nha mấy chú”);
    }
    
    8: là hàm được gọi nếu câu trả lời là
    // Báo lỗi nè!
    expression();
    var expression = function (){
        alert(“Gọi tui là lỗi nha mấy chú”);
    }
    
    9.
  • var expression = function (){
        alert(“Gọi tui là lỗi nha mấy chú”);
    }
    expression();
    
    0: là hàm được gọi nếu câu trả lời là
    var expression = function (){
        alert(“Gọi tui là lỗi nha mấy chú”);
    }
    expression();
    
    1.

Code triển khai hàm

var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
2 như sau:

myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
6

Trong ví dụ trên, hàm confirm bật ra một hộp thoại hỏi người dùng "Bạn muốn tiếp tục thực hiện chương trình không?".

Nếu người dùng chọn OK thì giá trị của

var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
3 là
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
4. Khi đó, hàm
// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
8 được gọi. Ngược lại, khi
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
3 là
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
7 thì hàm
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
0 được gọi.OK thì giá trị của
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
3 là
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
4. Khi đó, hàm
// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
8 được gọi. Ngược lại, khi
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
3 là
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
7 thì hàm
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
0 được gọi.

Ở đây, hai tham số

// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
8 và
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
0 gọi là hàm callback hay gọi tắt là callback.hàm callback hay gọi tắt là callback.

💡 Ý tưởng của hàm callback là hàm này được truyền vào hàm khác, để gọi lúc cần thiết.hàm callback là hàm này được truyền vào hàm khác, để gọi lúc cần thiết.

Liên hệ thực tế như khi bạn gọi điện đến nhà một người bạn. Nhưng người bạn cần tìm không có nhà, mà bạn không thể giữ điện thoại đợi cho đến khi người đó về.

Vì vậy, bạn để lại lời nhắn, kèm số điện thoại để khi nào người đó về sẽ gọi lại cho bạn.

Có thể bạn quan tâm: Xử lý bất đồng bộ với callback, promise, async/await

Trong ví dụ trên, mình viết định nghĩa hai hàm

// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
8 và
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
0 sử dụng "function declaration". Nhưng bạn có thể thay thế bằng biểu thức hàm như sau:

myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
7

Vì thực tế là hai hàm

// Báo lỗi nè!
expression();
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
8 và
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
0 chỉ sử dụng bên trong hàm
var expression = function (){
    alert(“Gọi tui là lỗi nha mấy chú”);
}
expression();
2, nên mình có thể dùng function expression như trên mà không cần khai báo tên hàm.

📝 Những hàm như trên còn có tên gọi khác là "anonymous function" hay "hàm ẩn danh".

So sánh function expression với function declaration

Đọc đến đấy chắc bạn cũng đã khá hiểu về biểu thức hàm rồi phải không?

Sau đây, mình cùng xem những điểm khác nhau giữa biểu thức hàm (function expression) và định nghĩa hàm (function declaration).

► Cú pháp khai báo:

Function declaration: là hàm được định nghĩa độc lập, không nằm trong biểu thức hay câu lệnh nào cả.: là hàm được định nghĩa độc lập, không nằm trong biểu thức hay câu lệnh nào cả.

myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
8

Function expression: là hàm được định nghĩa với một biểu thức, sử dụng toán tử gán

function handleClick() {
        console.log("clicked")
    }
6.: là hàm được định nghĩa với một biểu thức, sử dụng toán tử gán
function handleClick() {
        console.log("clicked")
    }
6.

myFunc();
function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
9

► Thời gian khởi tạo:

Function declaration: hàm được xử lý sớm hơn vị trí mà hàm được định nghĩa. Nghĩa là bạn có thể gọi hàm trước khi định nghĩa hàm.: hàm được xử lý sớm hơn vị trí mà hàm được định nghĩa. Nghĩa là bạn có thể gọi hàm trước khi định nghĩa hàm.

function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
0

Function expression: hàm được tạo ra tại thời điểm chương trình thực thi xử lý tới đó. Nghĩa là bạn không thể gọi biểu thức hàm trước khi định nghĩa nó.: hàm được tạo ra tại thời điểm chương trình thực thi xử lý tới đó. Nghĩa là bạn không thể gọi biểu thức hàm trước khi định nghĩa nó.

Ví dụ sau bị lỗi cú pháp:

function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
1

► Phạm vi của function declaration và function expression:

Khi sử dụng strict mode, function declaration có phạm vi trong block. Bạn có thể gọi hàm ở bất kỳ đâu trong block đó, nhưng không sử dụng được ở bên ngoài.block. Bạn có thể gọi hàm ở bất kỳ đâu trong block đó, nhưng không sử dụng được ở bên ngoài.

Ví dụ sau bị lỗi cú pháp:

function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
2

► Phạm vi của function declaration và function expression:

Khi sử dụng strict mode, function declaration có phạm vi trong block. Bạn có thể gọi hàm ở bất kỳ đâu trong block đó, nhưng không sử dụng được ở bên ngoài.

function myFunc (){
    alert(“Hello Góc Kinh Nghiệm”);
}
myFunc();
3

📝 Dĩ nhiên, đoạn code trên chỉ là ví dụ minh họa. Thực tế, bạn có nhiều cách để giải quyết bài toán này.

Nên viết hàm theo function declaration hay function expression?

Câu trả lời là: tùy bạn.tùy bạn.

Tùy thuộc vào phong cách và mục đích của bạn mà lựa chọn cho phù hợp.

Tuy nhiên, theo quan điểm cá nhân thì mình thấy dùng function declaration sẽ dễ nhìn hơn. Ngoài ra, function declaration còn giúp bạn thoải mái hơn trong việc cấu trúc code (không phụ thuộc nhiều vào thứ tự code).function declaration sẽ dễ nhìn hơn. Ngoài ra, function declaration còn giúp bạn thoải mái hơn trong việc cấu trúc code (không phụ thuộc nhiều vào thứ tự code).

Tổng kết

Bản chất của hàm là giá trị. Vì vậy, bạn có thể thoải mái gán, sao chép và truyền một hàm vào hàm khác dạng tham số.giá trị. Vì vậy, bạn có thể thoải mái gán, sao chép và truyền một hàm vào hàm khác dạng tham số.

Khi một hàm được định nghĩa độc lập thì đó gọi là "function declaration". Ngược lại, khi một hàm được định nghĩa bên trong một biểu thức, đó gọi là "function expression".

Khi một hàm được truyền vào bên trong hàm khác để gọi lại khi cần thiết, hàm đó được gọi là "hàm callback".

Function declaration được xử lý trước khi chương trình chạy đến đó. Function declaration có phạm vi trong block, nên bạn có thể gọi hàm ở bất kỳ đâu trong block. được xử lý trước khi chương trình chạy đến đó. Function declaration có phạm vi trong block, nên bạn có thể gọi hàm ở bất kỳ đâu trong block.

Function expression được tạo ra tại thời điểm chương trình chạy đến vị trí khởi tạo hàm. Nên bạn chỉ gọi được hàm sau khi đã khởi tạo. được tạo ra tại thời điểm chương trình chạy đến vị trí khởi tạo hàm. Nên bạn chỉ gọi được hàm sau khi đã khởi tạo.

★ Nếu bạn thấy bài viết này hay thì hãy theo dõi mình trên Facebook để nhận được thông báo khi có bài viết mới nhất nhé: