Computer >> Máy Tính >  >> Lập trình >> Javascript

Biểu thức hàm so với Khai báo hàm trong JavaScript - Sự khác biệt là gì?

Tìm hiểu về sự khác biệt giữa khai báo hàm và biểu thức hàm trong JavaScript.

Đây là một biểu thức hàm:

// Function expression
let excuteMe = function () {
    console.log('Function Expression')
}

Đây là một khai báo hàm:

// Function declaration
function excuteMe() {
    console.log('Function Declaration')
}

Các biểu thức và khai báo hàm khá nhiều làm điều tương tự. Trong cả hai ví dụ trên, bạn sẽ gọi chúng như sau executeMe() và sau đó họ thực thi bất kỳ mã nào bên trong khối mã của họ {..} .

Nhưng có một sự khác biệt, không phải ở những gì họ làm, mà là cách thức chúng được thực hiện - hay đúng hơn là đơn đặt hàng chúng được đọc và thực thi - và điều này rất quan trọng.

Chức năng này sẽ chạy tốt:

// Call function declaration
executeMe()

// Function declaration
function excuteMe() {
    console.log('Function Declaration')
}

Tuy nhiên, hàm sẽ không chạy tốt (nó sẽ xuất hiện một lỗi):

// Call function
executeMe()

// Function expression
let excuteMe = function () {
    console.log('Function Expression')
}

Để hiểu tại sao ví dụ đầu tiên (khai báo hàm) hoạt động, nhưng ví dụ thứ hai (biểu thức hàm) thì không, bạn phải tìm hiểu những gì hoisting có trong JavaScript, và sau đó nó sẽ bắt đầu có ý nghĩa.

Palăng

Trong JavaScript, mã được thực thi từ trên xuống dưới. Thông thường, bạn chỉ có thể sử dụng một biến sau phần khai báo của nó trong tệp script của bạn (theo thứ tự), tuy nhiên, khai báo hàm được đưa lên đầu bởi trình duyệt web, trước khi bất kỳ mã nào được thực thi.

Lưu trữ có nghĩa là trình thông dịch mã của trình duyệt của bạn luôn luôn biết về (đã đọc) các khai báo hàm của bạn trước khi chúng được gọi (yêu cầu thực thi).

Vì vậy, bạn có thể gọi và thực hiện khai báo hàm của mình từ bất cứ đâu trong tệp JavaScript của bạn, ngay cả trước khi khai báo hàm tồn tại vật lý trong tệp tập lệnh của bạn, theo thứ tự. Điều này làm cho các khai báo hàm là duy nhất.

Khai báo hàm

Trước khi có thể chạy bất kỳ mã nào, trình duyệt của bạn sẽ tải (đọc) toàn bộ tệp tập lệnh JS của bạn và vì khai báo hàm được chuyển lên đầu (được nâng) của thứ tự thực thi, mã của bạn thực sự được thực thi theo thứ tự này bởi trình thông dịch:

// 1. Function declaration
function excuteMe() {
    console.log('Function Declaration')
}

// 2. Call to function declaration
executeMe()

Ngay cả khi mã của bạn được viết thực tế trong tệp kịch bản của bạn theo thứ tự ngược lại:

// Call to function declaration
executeMe()

// Function declaration
function excuteMe() {
    console.log('Function Declaration')
}

Đó là lý do tại sao không thành vấn đề nếu bạn thực hiện lệnh gọi đến khai báo hàm của mình trước hoặc sau khi nó được xác định trong tệp tập lệnh của bạn. Cả hai cách tiếp cận sẽ hoạt động vì JavaScript luôn tải các khai báo hàm trước khi nó chạy hàm cuộc gọi cho các khai báo chức năng đó.

Biểu thức hàm không hoist

Biểu thức hàm không được kéo lên (không được đọc trước). Biểu thức hàm chỉ được đọc khi trình thông dịch tiếp cận dòng mã đó trong tệp tập lệnh của bạn. Vì vậy, nếu biểu thức chức năng của bạn tồn tại về mặt vật lý sau lệnh gọi hàm của bạn (theo thứ tự) thì trình thông dịch JavaScript chạy trong trình duyệt của bạn không thể thực thi nó.

Vì vậy, điều này sẽ không hoạt động:

// Call function expression
executeMe()

// Function expression
let excuteMe = function () {
    console.log('Function Expression')
}

Đoạn mã trên sẽ cung cấp cho bạn một lỗi vì bạn đang cố chạy một hàm (executeMe() ) trước khi trình thông dịch mã của trình duyệt của bạn biết (đã đọc) về sự tồn tại của biểu thức hàm của bạn.

Hoán đổi thứ tự mã và nó sẽ hoạt động:

// Function expression
let excuteMe = function () {
    console.log('Function Expression')
}

// Call function expression
executeMe()

Đoạn mã trên hoạt động nhờ vào thứ tự mã. Đầu tiên, trình duyệt của bạn sẽ đọc dòng (từ trên xuống dưới) với biến let executeMe có chứa biểu thức hàm của bạn - và sau đó nó được yêu cầu thực thi nó sau đó với executeMe() .

Bạn nên sử dụng cái nào?

Điều quan trọng không phải là bạn sử dụng khai báo hàm hay biểu thức hàm. Sẽ không tạo ra hoặc phá vỡ sự nghiệp của bạn. Nhất quán là cách quan trọng hơn. Chọn một phong cách và gắn bó với nó, ít nhất là trong cùng một dự án.

Quan trọng hơn nữa, nếu bạn tham gia một nhóm sử dụng biểu thức hàm, thì bạn nên làm theo công thức của họ để giữ cho cơ sở mã nhất quán, bất kể sở thích cá nhân của bạn là gì.

Một trường hợp tốt để sử dụng biểu thức hàm là chúng buộc bạn phải sử dụng cấu trúc mã chặt chẽ hơn, điều này làm cho mã của bạn dễ đoán hơn. Khai báo hàm được tha thứ vì bạn có thể gọi chúng từ bất kỳ đâu trong tập lệnh của mình và do đó có thể dẫn đến cấu trúc mã không nhất quán, đặc biệt nếu nhiều nhà phát triển đang làm việc trên cùng một dự án.

Một trường hợp hay (có thể tranh luận) để sử dụng khai báo hàm là nếu bạn có một số hàm gọi các hàm khác, nhưng bạn nhầm lẫn về và vì một số lý do không thể làm cho biểu thức hàm của bạn thực thi vì một số nhầm lẫn thứ tự