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
5 theo sau nó là:const hello = function sayHello[] {
console.log["Hello World"];
}
- 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
6.const hello = function sayHello[] { console.log["Hello World"]; }
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ự
7.const hello = function sayHello[] { console.log["Hello World"]; }
7.const hello = function sayHello[] { console.log["Hello World"]; }
- Tên hàm không được bắt đầu bằng số, các ký tự khác ký tự
7.const hello = function sayHello[] { console.log["Hello World"]; }
7.const hello = function sayHello[] { console.log["Hello World"]; }
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["//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
function doSomeThing[] {
// Do Something
}
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"];
}
0Gọ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"];
}
2const sayHello = function[] {
console.log["Hello World"];
}
1
const sayHello = function[] {
console.log["Hello World"];
}
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"];
}
3Bạn có thể tính giai thừa của
3 tới function doSomeThing[] {
// Do Something
}
4 như sau:function doSomeThing[] {
// Do Something
}
function doSomeThing[] {
// Do Something
}
3 tới function doSomeThing[] {
// Do Something
}
4 như sau:const sayHello = function[] {
console.log["Hello World"];
}
4Có 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
5, có thể được dùng để đạt được mục tiêu này.function doSomeThing[] {
// Do Something
}
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"];
}
5Cá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à
6.function doSomeThing[] {
// Do Something
}
function doSomeThing[] {
// Do Something
}
6.Trong ví dụ sau, nếu không có giá trị nào được truyền cho
8, giá trị của nó sẽ là function doSomeThing[] {
// Do Something
}
6 khi thực hiện tính toán function doSomeThing[] {
// Do Something
}
0, và việc gọi hàm function getWebsite[] {
console.log["//codelearn.io/"];
}
1 sẽ trả về function getWebsite[] {
console.log["//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:function getWebsite[] {
console.log["//codelearn.io/"];
}
const sayHello = function[] {
console.log["Hello World"];
}
6Khi 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
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
}
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"];
}
72. 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["//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"];
}
8Arrow 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ự
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["//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["//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["//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["//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["//codelearn.io/"];
}
7.function getWebsite[] {
console.log["//codelearn.io/"];
}
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"];
}
9Ví 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"];
}
02. 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"];
}
13. 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"];
}
2Closures
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"];
}
3Trong ví dụ trên, hàm
9 tạo ra một biến local function getWebsite[] {
console.log["//codelearn.io/"];
}
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 funName[param_1, ..., pram_n] {
//code
}
9 là một closure. Do đó, nó có thể sử dụng biến function getWebsite[] {
console.log["//codelearn.io/"];
}
0 được khai báo trong function funName[param_1, ..., pram_n] {
//code
}
9 để log function getWebsite[] {
console.log["//codelearn.io/"];
}
0 trong console sau khi function funName[param_1, ..., pram_n] {
//code
}
9 được trả lại.function getWebsite[] {
console.log["//codelearn.io/"];
}
function getWebsite[] {
console.log["//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["//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["//codelearn.io/"];
}
9 để log function funName[param_1, ..., pram_n] {
//code
}
0 trong console sau khi function getWebsite[] {
console.log["//codelearn.io/"];
}
9 được trả lại.VD2:
const hello = function sayHello[] {
console.log["Hello World"];
}
4Chú ý, biến
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
}
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!