Hàm trong ECMAScript

Xem thêm các chuyên mục:

1- Hàm (Function) là gì?

Trong ECMAScript, hàm (function) là một chương trình con, nó bao gồm các lệnh để thực hiện một nhiệm vụ nào đó. Và khi bạn muốn thực hiện nhiệm vụ như vậy tại một nơi nào đó trong ứng dụng bạn chỉ cần gọi hàm này. Hàm giúp bạn dễ dàng bảo trì ứng dụng và dễ dàng tái sử dụng code.
Dưới đây là cú pháp để định nghĩa một hàm đơn giản và không có tham số:
function function_name() {
   // function body
}
 
Ví dụ:
my-first-function-example.js
// Define a function:
function greeting()  {
   console.log("Hello World!");
}

// Call function.
greeting();
Một hàm tiêu chuẩn trong ECMAScript được định nghĩa theo cú pháp dưới đây:
function function_name(parameter1, parameter2, .., parameterN) {

   // Function body
   // return ....
}
  • Sử dụng từ khóa function để định nghĩa một hàm.
  • Hàm có thể có 0 hoặc nhiều tham số (Parameter).
  • Hàm luôn trả về một giá trị, nếu không chỉ rõ giá trị này, nó sẽ trả về underfined. Để trả về một giá trị chúng ta sử dụng từ khóa return.
standard-function-example.js
function calculateTax(salary)  {

    if(salary >= 1000) {
         // The function will end here
         return salary * 20 / 100;
    }
    if(salary >= 500)  {
         // The function will end here
         return salary * 10 / 100;
    }
    return 0;
}

let tax = calculateTax(2000);
console.log("Salary: 2000, tax: " + tax);

tax = calculateTax(800);
console.log("Salary: 800, tax: " + tax);


tax = calculateTax(300);
console.log("Salary: 300, tax: " + tax);

2- Hàm với tham số mặc định

Trong ES6, một hàm cho phép các tham số được khởi tạo với các giá trị mặc định, giá trị mặc định này sẽ được sử dụng nếu bạn không truyền (pass) giá trị cho tham số này (Hoặc truyền giá trị undefined) khi gọi hàm. Giống với ví dụ dưới đây:
default-params-example1.js
function add(a, b = 1) {
   return a+b;
}

// Test
let value = add(2, 3);

console.log(value); // 5


// Test
value = add(9);

console.log(value); // 10
default-params-example2.js
function calculateTax(salary = 1000, rate = 0.2) {
   return salary * rate;
}

// Test
console.log (calculateTax() ) ; // 1000 * 0.2 = 200

console.log (calculateTax(2000) ) ; // 2000 * 0.2 = 400

console.log (calculateTax(3000, 0.5) ) ; // 3000 * 0.5 = 1500

console.log (calculateTax(undefined, 0.5) ) ; // 1000 * 0.5 = 500

3- Tham số Varargs

Tham số Varargs (Hoặc cũng còn được gọi là "Rest Parameters" (Các tham số còn lại) ) là một tham số đặc biệt của hàm. Bạn có thể truyền 0, 1 hoặc nhiều giá trị cho tham số Varargs.
Các đặc điểm của tham số Varargs:
  • Nếu một hàm có tham số Varargs thì tham số này phải là tham số cuối cùng của hàm.
  • Một hàm có nhiều nhất 1 tham số Varargs.
function myFunction(param1, param2, ... paramVarargs)  {

}
varargs-param-example.js
function showInfo(name, ... points)  {
    console.log("------------ ");
    console.log("Name: " + name);

    console.log("Array length: "+ points.length);

    for(let i=0; i< points.length; i++)  {
      console.log( points[i] );
    }
}

showInfo("Tom", 52, 82, 93);

showInfo("Jerry", 10, 50);

showInfo("Donald");

4- Hàm nặc danh (Anonymous Function)

Một hàm không có tên được gọi là một hàm nặc danh ( Anonymous Function). Các hàm nặc danh được tạo một cách động tại thời điểm chạy (runtime) của chương trình. Nó cũng có các tham số và trả về giống như một hàm thông thường.
Bạn cũng có thể khai báo một biến với giá trị là một hàm nặc danh. Một biểu thức như vậy được gọi là biểu thức hàm ( Function Expression).
var myVar = function( parameters ) {
   // ....
}
Ví dụ:
anonymos-function-example.js
// Function expression
var f = function(name){
  return "Hello " + name;
}

// Call it.
var value = f("Tom");

console.log( value ); // Hello Tom.
Ví dụ, tạo một hàm nặc danh và gọi nó ngay lập tức. Trong trường hợp này hàm nặc danh được tạo ra chỉ để sử dụng một lần duy nhất.
anonymous-function-example2.js
// Create anonymous function and call immediately
(function()  {
   var now = new Date();

   console.log("Now is " + now);
}) () ;


// Create anonymous function and call immediately
(function(name)  {

   console.log("Hello " + name);
}) ("Tom") ;
 

5- Function Constructor

Trong ECMAScript, chúng ta có lớp Function, vì vậy bạn có thể tạo một hàm thông qua các constructor của lớp này.
var variableName = new Function(paramName1, paramName2, ..., paramNameN, "Function Body");
Ví dụ:
function-constructor-example.js
var myMultiple = new Function( "x", "y", "return x * y");

console.log( myMultiple (3, 4) ); // 12


function showTotal()  {
   let quantity = 4;
   let price = 5;

   console.log("Total: " + myMultiple(quantity, price) );
}

showTotal();

6- Hàm Lambda (Arrow)

Hàm Lambda thực chất là một hàm ẩn danh được viết theo một cú pháp ngắn gọn. Hàm này cũng được gọi là "Hàm mũi tên" (Arrow Function) vì trong cú pháp của nó có dấu mũi tên ( => ).
Dưới đây là một hàm nặc danh:
Anonymous Function
// Anonymous Function
var func = function(a, b)  {
  return a * b;
}
Cũng hàm ở trên nhưng chúng ta viết ngắn gọn hơn theo cú pháp Lambda.
// Arrow function
var func = (a, b) => {
   return a * b;
}

console.log( func( 5, 6 ) ); // 30
Nếu hàm không có tham số:
// Function without parameter.
var func  =  () =>  {
    console.log("Hello World");
}

console.log( func( ) ); // Hello World
Nếu hàm có một tham số duy nhất, bạn có thể không cần viết cặp dấu ngặc tròn (parentheses) ( ):
// Function with one parameter.
var func  = name =>  {
    console.log("Hello " + name);
}

console.log( func( "Tom" ) ); // Hello Tom
Nếu thân của hàm chỉ có một biểu thức duy nhất, bạn có thể không cần phải viết cặp dấu ngặc móc (brackets) { } và phải bỏ từ khóa return (Nếu có).
// Body has only one expression.
var func = (name)  => {

   console.log("Hello " + name)
}

// Body has only one expression.
var func  = (name) =>  console.log("Hello " + name);
 
// Body has only one expression.
var func = (a, b)  => {

    return a * b;
}

// Body has only one expression.
var func  = (a, b) =>  a * b;
Với một hàm có một tham số, và thân hàm có một biểu thức duy nhất bạn có thể viết ngắn gọn nhất giống như ví dụ dưới đây:
var func = (name)  => {
  console.log("Hello " + name);
}

// Shortest:
var func = name => console.log("Hello " + name);

7- Generator Function

Generator Function là một tính năng mới được đưa vào ECMAScript 6 (ES6). Để khai báo một Generator Function chúng ta sử dụng từ khóa function*.
function* functionName( param1, param2, ..., paramN) {
   // Statements
}
Về cơ bản Generator Function là một hàm có khả năng tạm ngưng thực thi, và có thể tiếp tục chạy tiếp ở một thời điểm nào đó. Generator Function trả về một đối tượng Iterator một cách không tường minh. Trong nội dung của hàm này bạn chỉ cần định nghĩa các giá trị cho các phần tử trong Iterator đó.
Có thể bạn sẽ thực sự khó hiểu với các giải thích ở trên, chúng ta sẽ xem một ví dụ:
generator-function-example.js
function* season()  {
   yield "Spring";
   yield "Summer";
   yield "Autumn";
   yield "Winter";
}

// This method return an Iterator.
var seasonIterator = season();

let value1 = seasonIterator.next().value;
console.log(value1); // Spring

let value2 = seasonIterator.next().value;
console.log(value2); // Summer

let value3 = seasonIterator.next().value;
console.log(value3); // Autumn

let value4 = seasonIterator.next().value;
console.log(value4); // Winter
Ví dụ ngắn gọn hơn:
function* season()  {
   yield "Spring";
   yield "Summer";
   yield "Autumn";
   yield "Winter";
}

// This method return an Iterator.
var seasonIterator = season();

let e;
while( !(e = seasonIterator.next()).done ) {
  console.log(e.value);
}
Khi một hàm thông thường được gọi nó sẽ thực thi cho tới khi giá trị được trả về hoặc kết thúc hàm. Trong thời gian đó Caller Function (Hàm gọi) không thể điều khiển sự thực thi của Called Function (Hàm được gọi).
Caller Function có thể điều khiển được sự thực thi của Called Function nếu hàm được gọi là một Generator Function. Dưới đây là một ví dụ như vậy:
generator-function-example3.js
function* season()  {
   console.log("Do something in Spring");
   yield "Spring";// Spring Stop here!

   console.log("Do something in Summer");
   yield "Summer";// Summer Stop here!

   console.log("Do something in Autumn");
   yield "Autumn";// Autumn Stop here!

   console.log("Do something in Winter");
   yield "Winter";// Winter Stop here!
}

// This method returns an Iterator.
var seasonIterator = season();

let e;
while( !(e = seasonIterator.next()).done ) {
   console.log(e.value);
   if(e.value === "Autumn") {
       console.log("OK Stop after Autumn");
       break;
   }  
}

Xem thêm các chuyên mục: