Function là một khái niệm quan trọng và một phần không thể thiếu trong JavaScript. Nó cho phép bạn định nghĩa và tái sử dụng các khối mã lệnh, giúp tăng tính module, khả năng mở rộng và sắp xếp mã nguồn.
Function trong JavaScript có thể được khai báo bằng hai cách: Function Declaration và Function Expression.
Function Declaration:
Copy codefunction myFunction() { // Mã lệnh của function }
Function Expression:
var myFunction = function() { // Mã lệnh của function };
Bạn có thể truyền tham số vào Function để thực hiện các tác vụ cụ thể và có thể sử dụng từ khóa return
để trả về giá trị từ Function.
Function cũng có phạm vi hoạt động (scope). Mỗi Function có phạm vi của riêng nó, và các biến khai báo trong Function không thể truy cập từ bên ngoài Function. Tuy nhiên, biến được khai báo trong phạm vi bên ngoài có thể được truy cập từ bên trong Function.
Function cũng có thể được gán vào biến, truyền như một đối số cho Function khác, và trả về từ một Function khác. Điều này cho phép Function được xem như là “công dân đầu tiên” trong JavaScript, có thể được sử dụng như bất kỳ giá trị nào khác.
Một khái niệm quan trọng khác liên quan đến Function trong JavaScript là Closures. Closures là khả năng của một Function để truy cập và sử dụng các biến từ phạm vi bên ngoài của nó, ngay cả khi Function đã hoàn thành việc thực thi.
Function là một yếu tố quan trọng trong việc phát triển ứng dụng JavaScript. Nó giúp tách biệt và tái sử dụng mã nguồn, tạo các khối mã lệnh độc lập, và mang lại tính linh hoạt và mở rộng cho dự án của bạn.
Xem thêm Scope trong JavaScript là gì ?
Các loại Function trong JavaScript
Trong JavaScript, có ba loại chính của Function: Function thông thường (Function Declaration), Function biểu thức (Function Expression) và Arrow Function. Dưới đây là mô tả và ví dụ về mỗi loại Function này:
- Function thông thường (Function Declaration): Function Declaration cho phép bạn khai báo một Function một cách trực tiếp và có thể sử dụng nó trước khi nó được định nghĩa. Đây là cách thông thường để khai báo Function trong JavaScript.
Ví dụ:
function myFunction() { // Mã lệnh của Function }
- Function biểu thức (Function Expression): Function Expression định nghĩa một Function và gán nó vào một biến hoặc một biểu thức khác. Cách này cho phép bạn tạo Function như một giá trị, và bạn chỉ có thể truy cập nó sau khi nó đã được gán.
Ví dụ:
var myFunction = function() { // Mã lệnh của Function };
- Arrow Function: Arrow Function là một cú pháp ngắn gọn và mới trong JavaScript, cho phép bạn định nghĩa Function bằng một cú pháp mũi tên (=>). Arrow Function tự động ràng buộc giá trị của từ khóa
this
với ngữ cảnh của nơi nó được định nghĩa.Ví dụ:
var myFunction = () => { // Mã lệnh của Arrow Function };
Các loại Function này có các cú pháp và cách hoạt động khác nhau, và bạn có thể sử dụng chúng tùy thuộc vào tình huống và yêu cầu cụ thể của bạn trong việc phát triển JavaScript.
Xem thêm AngularJS Scopes
Tham số và đối số trong Function
Trong JavaScript, tham số và đối số là hai khái niệm liên quan đến việc truyền dữ liệu vào một Function. Dưới đây là mô tả về tham số và đối số trong Function:
- Tham số (Parameters): Tham số là các biến được khai báo trong khai báo Function để nhận dữ liệu khi Function được gọi. Tham số được đặt trong cặp dấu ngoặc đơn sau tên Function và được phân tách bằng dấu phẩy nếu có nhiều tham số.
Ví dụ:
function greet(name) { console.log("Hello, " + name + "!"); }
- Đối số (Arguments): Đối số là các giá trị được truyền vào Function khi nó được gọi. Đối số được truyền trong cặp dấu ngoặc đơn sau tên Function và được phân tách bằng dấu phẩy nếu có nhiều đối số. Khi Function được gọi, giá trị của đối số sẽ được gán cho các tham số tương ứng trong khai báo Function.Ví dụ:
greet("John");
Trong ví dụ trên,"John"
là một đối số được truyền vào Functiongreet
. Giá trị của đối số"John"
sẽ được gán cho tham sốname
trong Function.
Khi gọi một Function, bạn có thể truyền đối số cho tất cả các tham số, hoặc chỉ một số tham số (nếu Function cho phép). Nếu không truyền đối số cho một tham số, giá trị của tham số đó sẽ là undefined
.
Ví dụ:
function addNumbers(a, b) { console.log(a + b); } addNumbers(5, 10); // Kết quả: 15 addNumbers(3); // Kết quả: NaN (undefined + 3)
Trong ví dụ trên, name là một tham số trong Function greet.
Trên đây là mô tả cơ bản về tham số và đối số trong JavaScript Function. Chúng cho phép bạn truyền và nhận dữ liệu trong Function để thực hiện các tác vụ cụ thể.
Xem thêm Các loại function
Function Scope và Lexical Scope
Function Scope và Lexical Scope là hai khái niệm quan trọng trong JavaScript liên quan đến phạm vi (scope) của biến và hàm. Dưới đây là mô tả về Function Scope và Lexical Scope:
- Function Scope: Function Scope xác định phạm vi của biến bên trong một Function. Biến được khai báo bên trong một Function chỉ có thể truy cập được trong phạm vi của Function đó. Nghĩa là biến chỉ được xác định trong Function và không thể truy cập từ bên ngoài Function hoặc từ các Function khác.
Ví dụ:
function myFunction() { var x = 5; // Biến x chỉ có thể truy cập được trong Function myFunction console.log(x); } myFunction(); // Kết quả: 5 console.log(x); // Lỗi: x is not defined
Trong ví dụ trên, biến x
được khai báo bên trong Function myFunction
và chỉ có thể truy cập được trong Function đó.
- Lexical Scope: Lexical Scope (còn được gọi là Static Scope) xác định phạm vi của biến dựa trên vị trí của mã lệnh trong mã nguồn. Nghĩa là biến được khai báo bên trong một khối mã (block) có thể truy cập được từ các khối mã con bên trong nó. Lexical Scope được xác định tại thời điểm viết mã và không thay đổi khi chương trình đang chạy.
Ví dụ:
function outerFunction() { var x = 10; function innerFunction() { console.log(x); // Biến x có thể truy cập được từ innerFunction vì nó nằm trong phạm vi của outerFunction } innerFunction(); } outerFunction(); // Kết quả: 10
Trong ví dụ trên, biến x
được khai báo trong outerFunction và có thể truy cập được từ innerFunction bên trong nó.
Lexical Scope cung cấp khả năng sắp xếp và quản lý biến theo các phạm vi nhất định trong mã nguồn. Điều này giúp tránh xung đột và lẫn lộ biến và tạo ra sự tổ chức và rõ ràng trong việc quản lý biến trong chương trình.
Tổng quan, Function Scope và Lexical Scope đóng vai trò quan trọng trong việc quản lý phạm vi và quyền truy cập biến trong JavaScript, giúp tạo ra mã nguồn rõ ràng và hạn chế xung đột biến.
Xem thêm Các Funtion trong Swift
Function là First-class Citizens
Trong JavaScript, Function được coi là “first-class citizens” hoặc “first-class objects”, có nghĩa là nó có các đặc tính và quyền lợi tương tự như các giá trị khác trong ngôn ngữ.
Dưới đây là một số đặc điểm của Function là first-class citizens trong JavaScript:
- Gán và truyền như giá trị: Function có thể được gán cho một biến hoặc một thuộc tính của một đối tượng, và có thể được truyền như một đối số cho một Function khác.
Ví dụ:
var myFunction = function() { console.log("Hello, World!"); }; var anotherFunction = myFunction; function executeFunction(func) { func(); } executeFunction(anotherFunction); // Kết quả: Hello, World!
- Có thể được trả về từ một Function khác: Một Function có thể trả về một Function khác như một giá trị kết quả.
Ví dụ:
function createGreeter() { return function() { console.log("Hello, World!"); }; } var greeter = createGreeter(); greeter(); // Kết quả: Hello, World!
- Có thể được khai báo bên trong một Function khác: Bạn có thể khai báo một Function bên trong một Function khác và truy cập nó trong phạm vi của Function bên ngoài.
Ví dụ:
function outerFunction() { function innerFunction() { console.log("I'm inside!"); } innerFunction(); // Kết quả: I'm inside! } outerFunction();
- Có thể được truyền như một đối số trong một Function khác: Bạn có thể truyền một Function như một đối số cho một Function khác và sử dụng nó trong Function đó.
Ví dụ:
function processArray(arr, callback) { for (var i = 0; i < arr.length; i++) { callback(arr[i]); } } function printElement(element) { console.log(element); } var myArray = [1, 2, 3, 4, 5]; processArray(myArray, printElement); // Kết quả: 1 2 3 4 5
Function là first-class citizens cho phép JavaScript có tính linh hoạt cao và khả năng xử lý hàm một cách mạnh mẽ. Bạn có thể tận dụng các đặc điểm này để viết mã nguồn dễ đọc, tái sử dụng và linh hoạt hơn.
Xem thêm Function Design trong UI
Closures trong JavaScript
Closure là một khái niệm quan trọng trong JavaScript, đề cập đến việc một hàm (function) có thể truy cập và ghi nhớ các biến bên ngoài phạm vi của nó, ngay cả khi hàm đó đã hoàn thành việc thực thi. Closure được tạo ra khi một hàm được khai báo bên trong một hàm khác và hàm nội bộ truy cập các biến của hàm bên ngoài.
Dưới đây là một ví dụ minh họa về closure trong JavaScript:
function outerFunction() { var outerVariable = 'Hello'; function innerFunction() { console.log(outerVariable); // Truy cập biến outerVariable bên ngoài phạm vi của hàm innerFunction } return innerFunction; // Trả về hàm innerFunction } var myFunction = outerFunction(); // Gán giá trị của innerFunction vào biến myFunction myFunction(); // Kết quả: 'Hello'
Trong ví dụ trên, hàm outerFunction
chứa một biến outerVariable
và một hàm innerFunction
. Khi gọi outerFunction
, nó trả về hàm innerFunction
và gán cho biến myFunction
. Sau đó, khi gọi myFunction()
, nó truy cập biến outerVariable
bên ngoài phạm vi của nó và in ra giá trị ‘Hello’.
Điểm quan trọng của closure là hàm nội bộ (innerFunction
trong ví dụ) tiếp tục giữ liên kết với phạm vi của hàm bên ngoài (outerFunction
), bao gồm các biến và tham số của nó, ngay cả khi hàm bên ngoài đã kết thúc việc thực thi. Điều này cho phép chúng ta tạo ra các hàm có khả năng lưu trữ thông tin và duy trì trạng thái dữ liệu.
Closures thường được sử dụng trong các tình huống như việc tạo ra các hàm gọi lại (callback functions), xử lý sự kiện (event handling), module pattern, và quản lý trạng thái dữ liệu.
Đảm bảo rằng bạn hiểu closures trong JavaScript có thể giúp bạn viết mã nguồn mạnh mẽ và linh hoạt hơn, và khai thác các tính năng của ngôn ngữ để tạo ra các ứng dụng phức tạp hơn.
Sử dụng Hàm Nâng Cao trong JavaScript
Trong JavaScript, việc lưu trữ các hàm trong các biến và chuyển đổi chúng giữa nhau là một khái niệm quan trọng. Dưới đây là một số thực hành hữu ích.
Lưu trữ các Function trong Biến
Hàm có thể được coi là các đối tượng ưu tiên trong JavaScript.
Bạn có thể gán một hàm cho một biến và tham chiếu đến chính hàm đó, như trong ví dụ sau:
function add(a, b) { return a + b; } let sum = add;
Bây giờ, bạn có thể gọi hàm thông qua cả add
và sum
.
Chuyển Một Function Sang Function Khác
Bạn có thể chuyển một hàm dưới dạng đối số vào một hàm khác.
Ví dụ: Hàm average
dưới đây chấp nhận một hàm làm đối số thứ ba:
function average(a, b, fn) { return fn(a, b) / 2; } let result = average(10, 20, sum);
Ở đây, chúng ta chuyển hàm sum
vào hàm average
.
Return Các Function Từ Các Function
Vì hàm là giá trị, bạn có thể trả về một hàm từ một hàm khác.
Hàm compareBy
dưới đây trả về một hàm so sánh dựa trên một thuộc tính:
function compareBy(propName) { return function (a, b) { let x = a[propName], y = b[propName]; if (x > y) { return 1; } else if (x < y) { return -1 } else { return 0; } } }
Bạn có thể sử dụng hàm compareBy
để sắp xếp mảng theo một thuộc tính cụ thể.
products.sort(compareBy('name')); // Sắp xếp theo tên products.sort(compareBy('price')); // Sắp xếp theo giá
Những thực hành này giúp bạn hiểu rõ hơn về khả năng linh hoạt của JavaScript trong việc xử lý hàm, từ việc lưu trữ chúng trong biến đến việc chuyển đổi và trả về chúng từ các hàm khác nhau.