Hướng dẫn function arguments javascript - đối số hàm javascript

Các hàm (Function) là một trong những nền tảng cơ bản trong Javascript. Vậy bạn đã nắm hết những kiến thức về Function trong Javascript chưa?

Function(Hàm) là gì?

Function (hàm, chức năng), gọi chung là subprogram (chương trình con) có thể được gọi ở bên ngoài hoặc bên trong chính nó. (hàm, chức năng), gọi chung là subprogram (chương trình con) có thể được gọi ở bên ngoài hoặc bên trong chính nó.

Nó bao gồm tập hợp các câu lệnh gọi là function body. Các giá trị có thể truyền đến một hàm, và một hàm có thể trả về giá trị. function body. Các giá trị có thể truyền đến một hàm, và một hàm có thể trả về giá trị. 

Bây giờ, với các ứng dụng hiện đại, các function có thể là một chương trình hoàn chỉnh, chứ không phải là khái niệm tổng quát như ''subprogram" nữa. Có sự khác nhau giữa function và procedure (thủ tục) rằng sự lý tưởng của function nên trả về một giá trị còn procedure thì không ( bây giờ điều này có thể thay đổi theo ngôn ngữ lập trình).

1. Khai báo hàm

Để khai báo hàm, chúng ta dùng từ khóa

const hello = function sayHello() {
     console.log("Hello World");
}
5 theo sau nó là:

  • Tên hàm
  • Danh sách các tham số truyền vào hàm, được đặt trong ngoặc đơn và cách nhau bởi dấu phẩy.
  • Các câu lệnh của JavaScript để tạo ra một hàm, được đặt trong ngoặc nhọn 
    const hello = function sayHello() {
         console.log("Hello World");
    }
    6.

Ví dụ, để định nghĩa một hàm in ra chữ "Hello World" ở console:

function sayHello () {
  console.log("Hello World");
}

2. Biểu thức hàm (Hàm trong biến)

Trong khi việc khai báo hàm ở trên là một câu lệnh về mặt cú pháp, các hàm cũng có thể tạo ra bằng một biểu thức hàm (function expression). Một hàm như vậy có thể nặc danh; nó không cần phải có tên. Ví dụ, hàm sayHello ở trên có thể được khai báo như sau:function expression). Một hàm như vậy có thể nặc danh; nó không cần phải có tên. Ví dụ, hàm sayHello ở trên có thể được khai báo như sau:

const sayHello = function() {
     console.log("Hello World");
}

Tuy nhiên, một cái tên có thể được cung cấp trong một biểu thức hàm. Việc cung cấp tên cho phép hàm có thể chạy chính nó, hoặc có thể sử dụng hệ thống debug để nhận dạng hàm trong stack traces.có thể được cung cấp trong một biểu thức hàm. Việc cung cấp tên cho phép hàm có thể chạy chính nó, hoặc có thể sử dụng hệ thống debug để nhận dạng hàm trong stack traces.

const hello = function sayHello() {
     console.log("Hello World");
}

3. Các ràng buộc về tên hàm

Javascript cũng giống như các ngôn ngữ khác nó cũng có các ràng buộc về tên hàm sau đây:

  • Tên hàm phải được bắt đầu bằng chữ cái (a-z,A-Z) hoặc ký tự 
    const hello = function sayHello() {
         console.log("Hello World");
    }
    7. 
    const hello = function sayHello() {
         console.log("Hello World");
    }
    7.
  • Tên hàm không được bắt đầu bằng số, các ký tự khác ký tự 
    const hello = function sayHello() {
         console.log("Hello World");
    }
    7.
    const hello = function sayHello() {
         console.log("Hello World");
    }
    7.

Các loại hàm

1. Hàm cơ bản

Đây là dạng hàm cơ bản nhất trong Javascript, cú pháp có dạng như sau:

function doSomeThing() {
     // Do Something
}

Trong đó: doSomeThing là tên của hàm bạn muốn đặt và

const hello = function sayHello() {
     console.log("Hello World");
}
9 là từ khóa bắt buộc.

Ví dụ: Tạo hàm in ra tên website codelearn ở console

function getWebsite() {
     console.log("https://codelearn.io/");
}

2. Hàm có tham số truyền vào

Đây là một dạng hàm rất hay được sử dụng, cú pháp có dạng như sau:

function funName(param_1, ..., pram_n) {
	//code
}

Trong đó:

  • funName là tên của hàm các bạn muốn đặt.là tên của hàm các bạn muốn đặt.
  • param_1,...,pram_n là các tham số mà các bạn muốn truyền vào hàm(không giới hạn số lượng). là các tham số mà các bạn muốn truyền vào hàm(không giới hạn số lượng).

VD: Tạo hàm tính tổng 2 số Tạo hàm tính tổng 2 số

function getSum(a, b) {
	console.log("Tổng: " + (a + b));
}

3. Hàm có tham số mặc định

Đây thực ra là dạng hàm có truyền tham số và đồng thời xét luôn giá trị mặc định cho các tham số đó. Cú pháp:

function funName(param_1 = value_1, ..., pram_n = value_2) {
	//code
}

Trong đó::

  • funName là tên của hàm các bạn muốn đặt.là tên của hàm các bạn muốn đặt.
  • param_1,...,pram_n là các tham số mà các bạn muốn truyền vào hàm(không giới hạn số lượng). là các tham số mà các bạn muốn truyền vào hàm(không giới hạn số lượng).
  • VD: Tạo hàm tính tổng 2 số là các giá trị tương ứng với các pram.

3. Hàm có tham số mặc định: với hàm getSum ở trên mình sẽ xét tham số mặc định cho nó.

function getSum(a = 5, b = 10) {
	console.log("Tổng: " + (a + b));
}

Đây thực ra là dạng hàm có truyền tham số và đồng thời xét luôn giá trị mặc định cho các tham số đó. Cú pháp:

value_1,...,value_n là các giá trị tương ứng với các pram.

  • VD: với hàm getSum ở trên mình sẽ xét tham số mặc định cho nó.
  • 4. Hàm có và không trả về giá trị

Trong javascript có hai loại hàm,đó là hàm có giá trị trả về và hàm không có giá trị trả về.: khai báo hàm getSum ở trên là hàm có giá trị trả về.

function getSum(a, b) {
	return a + b;
}

Đối với hàm có giá trị trả về thì phải sử dụng từ khóa function doSomeThing() { // Do Something }0

Và ngược lại đối với hàm không có giá trị trả về thì không có từ khóa

function doSomeThing() {
     // Do Something
}
0 một hàm sẽ không thực thi nó. Định nghĩa một hàm đơn giản chỉ là đặt tên cho hàm và chỉ định những việc cụ thể sẽ làm khi hàm đó được gọi.

VD: khai báo hàm getSum ở trên là hàm có giá trị trả về.

const sayHello = function() {
     console.log("Hello World");
}
0

Gọi hàm

Việc định nghĩa một hàm sẽ không thực thi nó. Định nghĩa một hàm đơn giản chỉ là đặt tên cho hàm và chỉ định những việc cụ thể sẽ làm khi hàm đó được gọi.trong phạm vi (in scope) khi nó được gọi, nhưng việc khai báo hàm có thể được hoisted (câu lệnh khai báo hàm xuất hiện bên dưới dòng gọi hàm trong đoạn code), như ví dụ này:

Ví dụ, nếu bạn định nghĩa hàm sayHello, bạn có thể gọi nó như sau:

Câu lệnh trên gọi hàm sayHello, kết quả trả về chữ "Hello World" tại console.

Các hàm phải đặt trong phạm vi (in scope) khi nó được gọi, nhưng việc khai báo hàm có thể được hoisted (câu lệnh khai báo hàm xuất hiện bên dưới dòng gọi hàm trong đoạn code), như ví dụ này:Điều này chỉ đúng khi định nghĩa một hàm bằng cách sử dụng các cú pháp ở trên (ví dụ 

function doSomeThing() {
     // Do Something
}
2). Điều này có nghĩa rằng function hoisting chỉ hoạt động với cách khai báo hàm thông thường (function declarations) - function hoisting không hoạt động đối với hàm được khai báo bằng biểu thức hàm (function expression). Ví dụ, đoạn code dưới đây sẽ không hoạt động:

const sayHello = function() {
     console.log("Hello World");
}
2

const sayHello = function() { console.log("Hello World"); }1

Phạm vi (scope) của một hàm là khoảng không gian bên trong hàm mà nó được khai báo (hoặc là cả chương trình, nếu nó được khai bảo ở top level, tức là nó không nằm trong hàm nào khác).

const sayHello = function() {
     console.log("Hello World");
}
3

Bạn có thể tính giai thừa của 

function doSomeThing() {
     // Do Something
}
3 tới
function doSomeThing() {
     // Do Something
}
4 như sau:
function doSomeThing() {
     // Do Something
}
3 tới
function doSomeThing() {
     // Do Something
}
4
 như sau:

const sayHello = function() {
     console.log("Hello World");
}
4

Có những cách khác để gọi hàm. Có nhiều trường hợp mà tại đó một hàm cần phải được gọi một cách tự động, hoặc làm thay đổi số lượng đối số truyền vào một hàm, hoặc trong trường hợp mà việc gọi hàm cần được gắn với một object nhất định được quyết định tại thời điểm runtime.

Điều đó lại hóa ra là các hàm tự bản thân chúng là các object, và kết quả là, những object này có các phương thức. Một trong số chúng, phương thức 

function doSomeThing() {
     // Do Something
}
5, có thể được dùng để đạt được mục tiêu này.

Phạm vi của hàm (Function Scope)

Các biến được định nghĩa bên trong một hàm không thể được truy cập từ nơi nào khác bên ngoài hàm, bởi vì biến đó được định nghĩa chỉ trong phạm vi của hàm. Tuy nhiên, một hàm có thể truy cập đến mọi biến và mọi hàm khác trong cùng phạm vi mà nó được định nghĩa.

Nói cách khác, một hàm được định nghĩa trong phạm vi global có thể truy cập tới tất cả các biến đã được định nghĩa trong phạm vi global. Một hàm được định nghĩa bên trong một hàm khác có thể truy cập đến tất cả biến được định nghĩa bên trong hàm cha của nó, và bất cứ biến nào khác mà hàm cha của nó có quyền truy cập đến. Các bạn có thể tham khảo ví dụ dưới đây:

const sayHello = function() {
     console.log("Hello World");
}
5

Các tham số của Function

Kể từ ES6, xuất hiện 2 dạng tham số mới: default parameters và rest parametersdefault parameters và rest parameters

1. Default parameters

Trong JavaScript, các tham số của function được mặc định là 

function doSomeThing() {
     // Do Something
}
6. Tuy nhiên, trong một số trường hợp nó có thể hữu ích để thiết lập một giá trị mặc định khác. Đây chính xác là điều mà default parameters sẽ làm.

Khi không có default parameters (trước ES6)

Trong quá khứ, cách thông thường để thiết lập các giá trị mặc định là kiểm định giá trị của các tham số bên trong body của function và gán giá trị cho nó nếu nó là 

function doSomeThing() {
     // Do Something
}
6.
function doSomeThing() {
     // Do Something
}
6.

Trong ví dụ sau, nếu không có giá trị nào được truyền cho 

function doSomeThing() {
     // Do Something
}
8, giá trị của nó sẽ là 
function doSomeThing() {
     // Do Something
}
6 khi thực hiện tính toán 
function getWebsite() {
     console.log("https://codelearn.io/");
}
0, và việc gọi hàm 
function getWebsite() {
     console.log("https://codelearn.io/");
}
1 sẽ trả về 
function getWebsite() {
     console.log("https://codelearn.io/");
}
2. Tuy nhiên, điều này bị ngăn chặn bởi dòng thứ 2 trong ví dụ này:

const sayHello = function() {
     console.log("Hello World");
}
6

Khi có default parameters (sau ES6)

Với default parameters, việc kiểm tra thủ công bên trong body của function không còn cần thiết. Bạn có thể đơn giản chỉ là đặt 

function doSomeThing() {
     // Do Something
}
3 vào làm giá trị mặc định cho 
function doSomeThing() {
     // Do Something
}
8 ngay tại head của function:default parameters, việc kiểm tra thủ công bên trong body của function không còn cần thiết. Bạn có thể đơn giản chỉ là đặt 
function doSomeThing() {
     // Do Something
}
3 vào làm giá trị mặc định cho 
function doSomeThing() {
     // Do Something
}
8 ngay tại head của function:

const sayHello = function() {
     console.log("Hello World");
}
7

2. Rest parameters

Cú pháp rest parameter cho phép chúng ta dùng 1 mảng để đại diện cho số lượng vô hạn các đối số.rest parameter cho phép chúng ta dùng 1 mảng để đại diện cho số lượng vô hạn các đối số.

Trong ví dụ sau, hàm 

function getWebsite() {
     console.log("https://codelearn.io/");
}
1 sử dụng rest parameters để thu thập các đối số kể từ đối số hứ hai trở về đến hết. Hàm này sau đó sẽ nhân những đối số này với đối số đầu tiên.

const sayHello = function() {
     console.log("Hello World");
}
8

Arrow Function

Trong ES6, arrow function là một cú pháp mới dùng để viết các hàm trong JavaScript. Nó giúp tiết kiệm thời gian phát triển và đơn giản hóa phạm vi function (function scope).arrow function là một cú pháp mới dùng để viết các hàm trong JavaScript. Nó giúp tiết kiệm thời gian phát triển và đơn giản hóa phạm vi function (function scope).

Arrow function - còn được gọi là "fat arrow", là cú pháp được mượn từ CoffeeScript (một ngôn ngữ chuyển tiếp), cú pháp này là cách ngắn gọn hơn dùng để viết function. Ở đây sử dụng kí tự 

function getWebsite() {
     console.log("https://codelearn.io/");
}
6, trông giống như một mũi tên "béo". Arrow function là một hàm vô danh và nó thay đổi cách 
function getWebsite() {
     console.log("https://codelearn.io/");
}
7 bind đến function. Arrow function làm code của ta trông ngắn gọn hơn, giúp đơn giản hóa function scoping cũng như từ khóa 
function getWebsite() {
     console.log("https://codelearn.io/");
}
7.
- còn được gọi là "fat arrow", là cú pháp được mượn từ CoffeeScript (một ngôn ngữ chuyển tiếp), cú pháp này là cách ngắn gọn hơn dùng để viết function. Ở đây sử dụng kí tự 
function getWebsite() {
     console.log("https://codelearn.io/");
}
6, trông giống như một mũi tên "béo". Arrow function là một hàm vô danh và nó thay đổi cách 
function getWebsite() {
     console.log("https://codelearn.io/");
}
7 bind đến function. Arrow function làm code của ta trông ngắn gọn hơn, giúp đơn giản hóa function scoping cũng như từ khóa 
function getWebsite() {
     console.log("https://codelearn.io/");
}
7.

Dưới đây là 1 vài ví dụ về việc sử dụng Arrow fucntion trong JavascriptArrow fucntion trong Javascript

1. Trường hợp có nhiều tham số

const sayHello = function() {
     console.log("Hello World");
}
9

Ví dụ trên cho cùng một kết quả, tuy nhiên cú pháp với arrow function tốn ít dòng mã hơn. Trong trường hợp chỉ có một biểu thức thì không cần tới dấu ngoặc nhọn: Ví dụ trên có thể viết lại như sau:

const hello = function sayHello() {
     console.log("Hello World");
}
0

2. Trường hợp có 1 tham số

Dấu ngoặc đơn là không bắt buộc khi chỉ có 1 tham số.

const hello = function sayHello() {
     console.log("Hello World");
}
1

3. Trường hợp không có tham số

Dấu ngoặc đơn là bắt buộc khi không có tham số.

const hello = function sayHello() {
     console.log("Hello World");
}
2

Closures

Closures là một trong những chức năng quyền lực nhất của JavaScript. JavaScript cho phép lồng các function vào nhau, và cấp quyền cho function con, để function con có toàn quyền truy cập vào tất cả các biến và function được định nghĩa bên trong function cha (và tất cả biến và function mà function cha được cấp quyền truy cập đến). là một trong những chức năng quyền lực nhất của JavaScript. JavaScript cho phép lồng các function vào nhau, và cấp quyền cho function con, để function con có toàn quyền truy cập vào tất cả các biến và function được định nghĩa bên trong function cha (và tất cả biến và function mà function cha được cấp quyền truy cập đến).

Tuy nhiên, function cha không có quyền truy cập đến các biến và function được định nghĩa bên trong function con. Điều này tạo nên một dạng bảo mật khép kín cho các biến của function con.

Bên cạnh đó, vì function con có quyền truy cập đến scope của function cha, các biến và function được định nghĩa bên trong function cha sẽ vẫn tồn tại dù việc thực thi function cha đã kết thúc, nếu function con xoay sở để tồn tại lâu hơn thời gian sống của function cha. Một closure được tạo ra khi một function con bằng cách nào đó trở nên khả dụng với bất kỳ scope nào bên ngoài function cha.

Hãy xem các ví dụ sau đây để hiểu hơn về ClosuresClosures

VD1:

const hello = function sayHello() {
     console.log("Hello World");
}
3

Trong ví dụ trên, hàm 

function getWebsite() {
     console.log("https://codelearn.io/");
}
9 tạo ra một biến local 
function funName(param_1, ..., pram_n) {
	//code
}
0 và 
function funName(param_1, ..., pram_n) {
	//code
}
1 (một hàm in ra num trong console). Hàm 
function funName(param_1, ..., pram_n) {
	//code
}
1 không có bất kỳ biến local nào trong nó. Tuy nhiên, nó có quyền truy cập vào các biến bên ngoài function, bởi vì 
function getWebsite() {
     console.log("https://codelearn.io/");
}
9 là một closure. Do đó, nó có thể sử dụng biến 
function funName(param_1, ..., pram_n) {
	//code
}
0 được khai báo trong 
function getWebsite() {
     console.log("https://codelearn.io/");
}
9 để log 
function funName(param_1, ..., pram_n) {
	//code
}
0 trong console sau khi 
function getWebsite() {
     console.log("https://codelearn.io/");
}
9 được trả lại.
function getWebsite() {
     console.log("https://codelearn.io/");
}
9 tạo ra một biến local 
function funName(param_1, ..., pram_n) {
	//code
}
0 và 
function funName(param_1, ..., pram_n) {
	//code
}
1 (một hàm in ra num trong console). Hàm 
function funName(param_1, ..., pram_n) {
	//code
}
1 không có bất kỳ biến local nào trong nó. Tuy nhiên, nó có quyền truy cập vào các biến bên ngoài function, bởi vì 
function getWebsite() {
     console.log("https://codelearn.io/");
}
9 là một closure. Do đó, nó có thể sử dụng biến 
function funName(param_1, ..., pram_n) {
	//code
}
0 được khai báo trong 
function getWebsite() {
     console.log("https://codelearn.io/");
}
9 để log 
function funName(param_1, ..., pram_n) {
	//code
}
0 trong console sau khi 
function getWebsite() {
     console.log("https://codelearn.io/");
}
9 được trả lại.

VD2:

const hello = function sayHello() {
     console.log("Hello World");
}
4

Chú ý, biến 

function funName(param_1, ..., pram_n) {
	//code
}
8 được khai báo sau anonymous function nhưng vẫn có thể truy cập biến 
function funName(param_1, ..., pram_n) {
	//code
}
8. Điều này là do biến 
function funName(param_1, ..., pram_n) {
	//code
}
8 đã được khai báo trong function scope tại thời điểm được tạo ra, làm cho nó có sẵn khi anonymous function được thực thi.
function funName(param_1, ..., pram_n) {
	//code
}
8 được khai báo sau anonymous function nhưng vẫn có thể truy cập biến 
function funName(param_1, ..., pram_n) {
	//code
}
8. Điều này là do biến 
function funName(param_1, ..., pram_n) {
	//code
}
8 đã được khai báo trong function scope tại thời điểm được tạo ra, làm cho nó có sẵn khi anonymous function được thực thi.

Callback Function

Callback function có thể được hiểu nôm na như sau: callback tức là ta truyền một đoạn code (Hàm A) này vào một đoạn code khác (Hàm B). Tới một thời điểm nào đó, Hàm A sẽ được hàm B gọi lại (callback). Javascript là một ngôn ngữ lập trình hướng sự kiện và bất đồng bộ nên callback function đóng vai trò rất quan trọng, bạn sẽ truyền một callback function vào các sự kiện và xử lý bất đồng bộ đó.. có thể được hiểu nôm na như sau: callback tức là ta truyền một đoạn code (Hàm A) này vào một đoạn code khác (Hàm B). Tới một thời điểm nào đó, Hàm A sẽ được hàm B gọi lại (callback). Javascript là một ngôn ngữ lập trình hướng sự kiện và bất đồng bộ nên callback function đóng vai trò rất quan trọng, bạn sẽ truyền một callback function vào các sự kiện và xử lý bất đồng bộ đó..

Về Callback Function thì mình cũng đã có viết 1 bài riêng để chúng ta cùng tìm hiểu về nó. Các bạn có thể đọc thêm ở đây.

Tạm kết

Như vậy trong bài viết này, chúng ta đã cùng nhau tìm hiểu những vấn đề cơ bản về Function trong Javascript. Bạn thấy thế nào về JS, hãy đưa ra những ý kiến trong quá trình sử dụng js nhé. Nếu các bạn thấy bài viết hữu ích hãy rate 5* và share cho mọi người tham khảo!Bạn thấy thế nào về JS, hãy đưa ra những ý kiến trong quá trình sử dụng js nhé. Nếu các bạn thấy bài viết hữu ích hãy rate 5* và share cho mọi người tham khảo!

Hãy để lại comment để mình có thể hoàn thiện bản thân hơn trong tương lai. Cám ơn các bạn!