JavaScript: ES6: Hàm (Function)

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Hàm là khối lệnh có tên dùng để thực hiện một công việc cụ thể nào đó, nó có thể dể dàng bảo trì và tái sử dụng. Hàm được định nghĩa bằng cách sử dụng từ khóa function.

Cú pháp:

function tên_hàm(Các_đối_số_nhận_dữ_liệu) {
   // khối_lệnh_thực_thi_công_việc_cụ_thể
} 

Để hàm được thực thi thì ta phải gọi nó. Cú pháp gọi như sau:

function_name(Các_dữ_liệu)

Ví dụ:

//định nghĩa hàm
function test() {
   console.log("Hello function")
} 
//gọi hàm
test()

Output:

Hello function

Phân loại hàm

Các hàm được phần thành 2 loại chính là hàm trả về và hàm tham số.

Hàm trả về

Là loại hàm dùng để trả về giá trị sau khi xử lý dữ liệu, câu lệnh trả về ở đây là return.

Cú pháp:

function tên_hàm() {
   //khối_lệnh
   return dữ_liệu
}
  • Hàm trả về phải kết thúc bằng câu lệnh return.

  • Một hàm có thể trả về nhiều nhất một dữ liệu. Nói cách khác, chỉ có thể có một câu lệnh return được thực thi cho mỗi hàm.

  • Câu lệnh return phải là câu lệnh cuối cùng trong hàm nếu không các câu lệnh sau nó sẽ bị bỏ qua.

Ví dụ:

function retStr() {
   return "V1Study"
}
var val = retStr()
console.log(val)

Output:

V1Study

Hàm tham số

Tham số là loại cơ chế dùng để truyền dữ liệu cho các hàm xử lý. Các tham số tạo thành một phần của dấu hiệu nhận biết hàm. Dữ liệu được truyền cho hàm tại lời gọi hàm. Trừ khi được chỉ định rõ ràng, thì số lượng dữ liệu truyền cho hàm phải khớp với số lượng tham số được định nghĩa.

Cú pháp:

function tên_hàm(param1, param2, …, paramN) {
   khối_lệnh
}

Ví dụ:

function add( n1,n2) {
   var sum = n1 + n2
   console.log("The sum of the values entered "+sum)
}
add(12,13)

Output:

The sum of the values entered 25

Tham số mặc định của hàm

Trong ES6, hàm cho phép các tham số được khởi tạo các giá trị mặc định, nếu không có giá trị nào được truyền cho nó hoặc nó không được xác định.Ví dụ:

function addition(a, b = 1) { 
   return a+b; 
} 
console.log(addition(4))

Ở hàm trên thì b được đặt giá trị mặc định là 1, khi này 4 sẽ được truyền cho a. Output:

5

Giá trị mặc định của tham số sẽ được ghi đè nếu hàm truyền một giá trị cụ thể.

function addition(a, b = 1) {
   return a + b;
}
console.log(addition(4,2))

Trong trường hợp trên, a nhận 4, còn b nhận 2. Kết quả output:

6

Tham số rest

Tham số rest tương tự như trong Java. Tham số rest sẽ không giới hạn số lượng giá trị truyền cho một hàm. Tuy nhiên, tất cả các giá trị được truyền phải có cùng kiểu.

Ví dụ sử dụng:

function fun1(...params) {
   console.log(params.length);
}
fun1(); 
fun1(5);
fun1(5, 6, 7);

Đầu ra sau đây được hiển thị khi thực hiện thành công mã trên.

0 
1 
3

Lưu ý - Tham số rest phải là tham số cuối cùng trong danh sách tham số của hàm.

Hàm không tên (Anonymous)

Đây là loại hàm được tạo ra mà không mang bất kỳ một tên (định danh) nào. Loại hàm này thường được khai báo động khi chạy chương trình.

Cú pháp:

var tên_biến = function( các_đối_số ) { ... }

Ví dụ 1:

var ano = function(){ return "V1"}
console.log(ano())

Output:

V1

Ví dụ 2:

var area = function(x,y){ return x*y };
function prod() {
   var kq;
   kq = area(10,20);
   console.log("Area : " + kq)
}
prod()

Output:

Area : 200 

Hàm tạo Function

Ta hoàn toàn có thể định nghĩa một hàm theo cách rất linh hoạt bằng cách sử dụng hàm tạo Function() cùng với toán tử new.

Cú pháp:

var tên_biến = new Function(Arg1, Arg2, ..., "Thân_hàm");

Hàm tạo Function() chấp nhận số lượng đối số bất kỳ, trong đó đối số cuối là thân của hàm, nới chứa code xử lý dữ liệu trong đó các lệnh phân tách nhau bằng dấu chấm phẩy (;).

Hàm tạo Function() không được truyền bất kỳ đối số nào chỉ định tên cho hàm mà nó tạo.

Ví dụ:

var cons = new Function("a", "b", "return a+b;"); 
function test() { 
   var result
   result = cons(1,2); 
   console.log("Result : " + test)
} 
product()

Output:

Result : 3

Hàm đệ quy và hàm JavaScript

Hàm đệ quy là hàm gọi đến chính nó, trong hàm đệ quy cần cài đặt lệnh return và xác định điểm dừng. Kỹ thuật đệ quy được áp dụng tốt nhất khi ta cần gọi cùng một hàm nhiều lần với các tham số khác nhau từ trong một vòng lặp.

Ví dụ

function recu(n) {
   if(n<=0) {
      return 1;
   } else {
      return (n * recu(n-1))
   }
}
console.log(recu(6))

Ví dụ trên áp dụng kỹ thuật đệ quy để tính giai thừa (6!). Kết quả:

720

Ví dụ về hàm đệ quy ẩn danh

(function() { 
   var msg = "Hello Myself"
   console.log(msg)
})()

Hàm gọi chính nó bằng cách sử dụng một cặp dấu ngoặc đơn (). Kết quả:

Hello Myself

Hàm Lambda

Lambda đề cập đến các hàm ẩn danh trong lập trình. Hàm Lambda là một cơ chế ngắn gọn để biểu diễn các hàm ẩn danh. Các hàm dạng này còn được gọi là các hàm Mũi tên.

Phân tích hàm Lambda

Hàm Lambda gồm 3 phần:

  • Tham số - Có thể có hoặc không.

  • Mũi tên lambda có ký hiệu =>: Người ta còn gọi là đi vào toán tử.

  • Các lệnh - Nơi chứa phần xử lý dữ liệu của hàm.

Mẹo - Theo quy ước, việc sử dụng tham số một chữ cái được khuyến khích cho khai báo hàm nhỏ gọn và chuẩn xác.

Biểu thức Lambda

Đây là một biểu thức hàm ẩn danh chỉ đến một dòng lệnh. Cú pháp:

([param1, parma2, …, param n]) => Lệnh;

Ví dụ:

var test = (x) => 10 + x
console.log(test(10))

Output:

20

Lệnh Lambda

Đây là một khai báo hàm ẩn danh trỏ đến một khối lệnh. Cú pháp này được sử dụng khi thân hàm có nhiều dòng. Cú pháp:

([param1, parma2,…param n]) => {
   //khối lệnh
}

Ví dụ:

var test = ()=> {
   console.log("Lambda")
}
test()

Tham chiếu của hàm được trả về và được lưu trong biến test. Kết quả:

Lambda

Biến thể cú pháp

Nếu hàm có một tham số duy nhất thì ta viết như ví dụ sau:

var test = x=> { 
   console.log(x) 
} 
test(10)

Cặp ngoặc xoắn không bắt buộc khi chỉ có một lệnh, nếu không có đối số thì cần có cặp ngoặc tròn:

var test = ()=>console.log("Hello V1Study") 
test();

Biểu thức hàm và khai báo hàm

Biểu thức hàm và khai báo hàm là khác nhau, trong đó một khai báo hàm bị ràng buộc bởi tên hàm.

Sự khác biệt cơ bản giữa hai khái niệm này là khai báo hàm sẽ được phân tích cú pháp trước khi thực hiện, còn biểu thức hàm chỉ được phân tích cú pháp khi script engine gặp nó trong khi thực thi.

Khi trình phân tích cú pháp JavaScript gặp một hàm trong luồng code chính, nó sẽ hiểu đó là khai báo hàm, còn khi một hàm xuất hiện như một phần của câu lệnh, thì đó là biểu thức hàm.

Hoisting hàm

Cũng giống như các biến, các hàm cũng có thể được hoisting, khác ở một điểm là khi hàm khi được hoisting thì sẽ hoisting phần định nghĩa hàm thay vì chỉ hoisting tên của hàm.

Đoạn mã sau đây, minh họa việc hoisting hàm trong JavaScript.

funcHoist();
function funcHoist() {
   console.log("OK");
}

Output:

OK 

Tuy nhiên, các biểu thức chức năng không thể được hoisting. Đoạn code sau minh họa điều này:

funcHoist(); // TypeError: funcHoist() is not a function  
var funcHoist() = function() {
   console.log("OK"); 
};

Biểu thức hàm được gọi tức thì

Biểu thức hàm được gọi tức thì (Immediately Invoked Function Express - IIFE) có thể được sử dụng để tránh việc hoisting biến đổi từ bên trong các khối. Nó cho phép truy cập công khai vào các hàm trong khi vẫn giữ quyền riêng tư cho các biến được định nghĩa trong hàm. Mẫu này được gọi là một hàm ẩn danh tự thực hiện. Hai ví dụ sau đây giải thích rõ hơn về khái niệm này.

Ví dụ 1:

var vd1 = function() {
   var loop = function() {
      for(var a = 0; a<5; a++) {
         console.log(a);
      }
   }();
   console.log("a không thể được truy cập từ ngoài phạm vi khối, giá trị của x là :" + x);
}
vd1();

Ví dụ 2:

var vd2 = function() {
   (function() {
      for(var b = 0; b<5; b++) {
         console.log(b);
      }
   })();
   console.log("b không thể được truy cập từ ngoài phạm vi khối, b = " + b);
}
vd2();

Cả hai ví dụ sẽ hiển thị đầu ra sau.

0 
1 
2 
3 
4 
Uncaught ReferenceError: x is not define

Hàm tạo

Khi một hàm bình thường được gọi thì quyền điều khiển sẽ nằm trong hàm đó cho đến khi các lệnh trong hàm được thực hiện xong hoặc gặp lệnh return. Với các trình tạo trong ES6 thì các trình gọi hàm bây giờ có thể kiểm soát việc thực hiện hàm được gọi. Một trình tạo giống như một hàm thông thường ngoại trừ:

  • Các hàm có thể lấy lại quyền điều khiển cho người gọi bất cứ lúc nào.

  • Khi bạn gọi một bộ tạo thì nó không chạy ngay lập tức. Thay vào đó, bạn nhận lại một iterator. Hàm sẽ chạy khi bạn gọi phương thức tiếp theo của iterator.

Các trình tạo được biểu thị bằng cách thêm vào từ khóa hàm dấu hoa thị (*); còn lại thì cú pháp của chúng giống hệt với các hàm thông thường.

Ví dụ:

"use strict"
function* test() {
   // dấu * đánh dấu đây làm một generator
   yield 'đỏ';
   yield 'da cam';
   yield 'vàng';
   yield 'lục';
   yield 'lam';
   yield 'nâu';
   yield 'tím';
}
for(let mau of test()) {
   console.log(mau);
}

Generator cho phép giao tiếp hai chiều giữa trình gọi hàm và hàm được gọi. Điều này được thực hiện bằng cách sử dụng từ khóa yield.

Xét ví dụ sau:

function* ask() {
   const name = yield "Bạn tên gì?";
   const sport = yield "Bạn thích môn thể thao nào?";
   return `${name} thích môn thể thao ${sport}`;
}
const it = ask();
console.log(it.next());
console.log(it.next('Long'));
console.log(it.next('Bóng đá'));

Trình tự thực thi như sau:

  • Bộ tạo bắt đầu ở chế độ tạm dừng (paused); iterator được trả về.

  • it.next () sẽ cho phép nhập tên, bộ tạo tạm dừng, điều này được thực hiện bởi từ khóa yield.

  • Lời gọi it.next('Long') sẽ gán giá trị Long cho biến name và yield ra chuỗi "Bạn thích môn thể thao nào?", bộ tạo lại bị tạm dừng.

  • Lời gọi it.next ('Bóng đá') sẽ gán giá trị 'Bóng đá' cho biến sport và thực hiện câu lệnh return tiếp theo.

Kết quả:

{ 
   value: 'Bạn tên gì?', done: false 
} 
{
   value: 'Bạn thích môn thể thao nào?', done: false 
}
{
   value: 'Long thích môn thể thao Bóng đá', done: true 
}

Lưu ý: Các hàm của trình tạo không thể được biểu diễn bằng các hàm mũi tên.

» Tiếp: Sự kiện
« Trước: Vòng lặp
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!