Chức năng trả về cuộc gọi javascript
Chương hôm nay giới thiệu về hàm trong JavaScript, tưởng tượng đơn giản nhưng không đơn giản chút nào Show
Bài viết này là một phần của series JavaScript dành cho người không mới, giúp các bạn đã có kinh nghiệm code trong các ngôn ngữ khác nhanh chóng làm quen với JS Nếu được rất mong nhận được sự ủng hộ và đóng góp ý kiến của mọi người để hoàn thiện series A. Tổng quan về chức năng1. Tổng quanHàm (hàm) là một nhóm các câu lệnh có liên quan, được gom lại với nhau, được đặt tên và thực hiện một công việc gì đó. Hàm sử dụng giúp chế độ hạn chế trùng lặp, tăng tính sử dụng lại và tổ chức mã nguồn tốt hơn function has two section
Hàm có thể là riêng lẻ hoặc thuộc về một hàm hay đối tượng nào đó (hàm bên trong đối tượng được gọi là phương thức - phương thức) định nghĩa hàm Cú pháp cơ bản định nghĩa một hàm
Một hàm định nghĩa bao gồm từ khóa hàm, tên hàm, theo sau là danh sách tham số (tham số - viết tắt tham số) trong ngoặc kép. Cuối cùng là thân hàm bao gồm các câu lệnh trong cặp {} Gọi hàm (gọi) Hàm có thể chạy bằng cách gọi hàm (gọi - gọi) hoặc để hàm tự động chạy (tự gọi). Hàm tự động chạy sẽ được bàn sau Hàm có thể sử dụng riêng lẻ như một câu lệnh hoặc sử dụng trong một biểu thức (khi hàm này phải trả về giá trị bất kỳ đó)
Khi gọi hàm, cần truyền cho nó một số đối số. Các đối số này được đưa vào hàm và được chuyển vào các tham số tương ứng. Trong JS không bắt buộc, và cũng không kiểm tra truyền đối số có đầy đủ hay không, vậy bạn có thể truyền thiếu, thừa đối số cũng không sao. Các tham số bị thiếu thì sẽ có giá trị là không xác định, hoặc giá trị mặc định nếu có Chú ý, khi gọi hàm cần có trích dẫn (), dù có truyền đối số hay không. Ví dụ như sau
Nếu bạn chỉ viết 6 mà không phải là 7, thì thay vì hàm chạy, nó sẽ trả về hàm chính đó. Khi đưa ra đầu ra bên ngoài, thì nó sẽ trả về toàn bộ mã của hàmTrả về một giá trị Khi trả về câu lệnh, hàm sẽ thoát và trả về giá trị nếu có. Các lệnh còn lại sẽ không được thực hiện (ngoại trừ một số trường hợp như khối cuối cùng)
cẩu chức năng Chức năng được nâng (kéo lên), tương tự các biến khai báo với var. Kỹ thuật nâng hạ đã được nói tới trong các chương trình trước, nên không bàn nhiều ở đây
2. Chức năng & sự kiệnSự kiện HTML là những sự kiện xảy ra đối với phần tử cụ thể, ví dụ như click vào nút thì sự kiện onclick của nút được gọi,. Toàn bộ tên sự kiện là chữ thường, và có dạng thuộc tính của thẻ JS nội tuyến Bên trong thuộc tính sự kiện của thẻ, có thể chứa các đoạn mã JS
Khi sự kiện cụ thể được kích hoạt, thì mã trong sự kiện đó được chạy. Vì mã JS thường dài, nếu đặt hết vào thuộc tính sự kiện sẽ rắc rối, nên tốt nhất là sử dụng sự kiện để gọi một chức năng đã được định nghĩa từ trước
Về các sự kiện, các bạn sẽ được tìm hiểu trong DOM DOM từ khóa này Để biết được phần tử nào được nhận sự kiện nào, thì hãy sử dụng từ khóa this. Điều này trong một sự kiện thuộc tính mang ý nghĩa là phần tử nhận được thuộc tính đó
Thuộc tính 8 cơ bản được sử dụng để thay đổi nội dung của phần tử dừngChú ý, khi gọi hàm trong sự kiện, thì cái này không sử dụng được trong hàm. Ví dụ như after will not run 2____10Giải pháp cho vấn đề này là truyền đối tượng này cho hàm 9 như một tham số. Mã sửa lại như sau 1 2Sự kiện sẽ truyền điều này thành một tên tham số là 20. Khi vào hàm thì sử dụng tham số này thay vì thế này, nên kết quả mã chạy tốt3. từ khóa nàyTừ khóa này trong JS thực sự có nhiều nghĩa, nhưng cũng dễ dàng để nắm bắt được
B. Định nghĩa & gọi1. Định nghĩa hàm (nâng cao)biểu thức hàm Ngoài ra, chức năng khai báo (declare) hoặc định nghĩa (define) bình thường như sau 3Còn có cách viết khác là sử dụng hàm dạng biểu thức (biểu thức). Chức năng biểu thức có thể gán vào một biến, và biến này sẽ có kiểu chức năng 4Chú ý dòng 2, biểu thức gán cho biến 21 có dạng một hàm ẩn danh (ẩn danh) là một hàm không có tên. Và sử dụng chức năng trên các chức năng tương tự như bình thường 5Biểu thức hàm không được lưu trữ, vì bản thân nó là một giá trị (vế phải có dấu bằng), nên không được lưu trữ. Thực hiện biến vẫn được cẩu, nhưng chỉ là không được sử dụng như chức năng (giá trị là không xác định), nên coi như nó không được cẩu Hàm tạo hàm Cách khác nữa để tạo hàm là sử dụng Hàm tạo 6Hàm khởi tạo hàm nhận vào nhiều tham số, trong đó tham số cuối cùng là phần thân mã của hàm Không nên sử dụng hàm tạo chức năng, vì mã lỗi và không an toàn 2. Tham số và đối sốTham số và đối số Tham số (tham số - param) là các biến trong cặp () của hàm, đại diện cho các tham số được truyền vào trong hàm. Các tham số được coi như các biến cục bộ trong hàm và bị hủy khi hàm thực thi xong Đối số (argument) là những biến, giá trị thực được truyền vào hàm. Các đối số được chuyển vào bên trong hàm, biến thành các tham số theo đúng thứ tự 7Người ta nhắc tới tham số khi ở bên trong định nghĩa hàm, và gọi là tham số khi gọi hàm. Và tham số phải là biến (đối tượng biến, hàm biến cũng là biến), trong khi đối số có thể là bất cứ thứ gì có giá trị, như số, biến, hằng, biểu thức, hàm, Quy tắc tham số JS không định kiểu cho tham số, và cũng không kiểm tra lượng đối số truyền vào. Do đó, đối số truyền cho hàm có thể nhiều hơn, hoặc ít hơn số lượng tham số cần có. Những tham số không nhận được đối số (do thiếu phương tiện truyền tải) thì sẽ có giá trị là không xác định 8ES6 (ECMAScript 2015) cho phép hàm có giá trị mặc định cho tham số. Khi truyền không đủ đối số, thì những tham số bị thiếu thay vì có giá trị là không xác định, thì nó sẽ sử dụng giá trị mặc định 9Trong đoạn mã trên, số 10 truyền cho 22, 23 không nhận được đối số nào, nhưng vì 23 có giá trị mặc định nên giá trị lúc này của nó chính là giá trị mặc định 100. Còn 25 thì không có đối số, cũng không có giá trị mặc định nên nó mang giá trị không xác địnhĐối số đi qua Đây là khái niệm cực kỳ quan trọng khi học về hàm, trong mọi ngôn ngữ lập trình Trong JS, nếu đối số là kiểu nguyên thủy thì được truyền theo giá trị (theo giá trị). Một bản sao của đối số được tạo ra và đưa vào tham số, mọi thao tác trong hàm đều được thực hiện trên bản sao nên dữ liệu gốc không bị ảnh hưởng (khi hàm thực hiện xong) Đối với đối tượng đối số, thì truyền kiểu truyền theo tham chiếu (tham chiếu). Thực ra vẫn là truyền theo giá trị, nhưng giá trị ở đây là tham chiếu tới địa chỉ bộ nhớ, nếu các thay đổi trên tham chiếu thì ảnh hưởng tới dữ liệu gốc 3. lời gọi hàmGọi một chức năng Để gọi (gọi - gọi) một chức năng, hãy đặt tên cho nó và truyền cho nó danh sách các đối số. The number of argument not started must be match with the tham số 0Nếu hàm thuộc về một đối tượng, thì hàm gọi là phương thức (phương thức). Gọi phương thức tương tự như hàm gọi, nhưng phải có tên đối tượng và dấu chấm phía trước 1Thực hiện mọi chức năng trong JS đều là phương thức, các chức năng không thuộc đối tượng nào thực hiện thuộc về cửa sổ đối tượng. Do đó, ví dụ đầu tiên có thể viết lại như sau, cũng cho kết quả tương tự 2Khi hàm thuộc đối tượng, chúng ta gọi đối tượng là chủ sở hữu (chủ sở hữu) của hàm đó Gọi hàm như một hàm tạo Có thể gọi hàm bằng từ khóa mới, lúc này hàm được coi như là một hàm tạo. Constructor thường được sử dụng để khởi tạo một đối tượng mới 3Điều này trong trường hợp này không phải cửa sổ đối tượng, mà là đối tượng mới được tạo ra nhờ từ khóa mới. Đối tượng này sẽ được gán tham chiếu tới biến 26, do đó 26 là một đối tượng. Tuy nhiên, điều này lúc này không có giá trị (rỗng), và giá trị được thêm vào điều này sẽ được sử dụng để tạo đối tượng mớiVấn đề này sẽ được thảo luận kỹ hơn trong đối tượng chương trình Chức năng tự gọi (IIFE) Một hàm có thể được gọi tự động mà không cần lời gọi hàm, chúng có tên là hàm tự gọi, hoặc IIFE (Biểu thức hàm gọi ngay lập tức) 4Chú ý hai dòng trên, chúng ta có 2 cách để thực hiện một chức năng thành tự gọi
Hàm tự gọi tự động chạy khi được định nghĩa C. tính năng chức năng1. chức năng ẩn danhAnonymous function (hàm hide list) is a function no name, đơn giản vậy thôi 5Hàm ẩn danh thường được dùng trong biểu thức hàm, để viết nhanh một hàm chỉ dùng một lần. Hàm ẩn danh cũng được sử dụng để gọi lại, truyền dưới dạng tham số cho một hàm khác và hàm chính được gọi lại (gọi lại) sau một khoảng thời gian làm gì đó . Ngoài ra nó còn được sử dụng trong chức năng đóng hoặc cho chức năng tự gọi.2. đối tượng chức năngHàm cũng là một đối tượng trong JS, cũng có các thuộc tính (thuộc tính) và phương thức (phương thức). Chúng ta chỉ quan tâm tới hai đối tượng cơ bản nhất Phương thức toString() Use convert a function to string, mean is show full code of function that 6Đối số đối tượng Bên trong mỗi chức năng có một đối tượng ẩn là 28. Nó giống như một mảng các đối số được truyền vào, có thuộc tính 29 để lấy độ dài. Chú ý các đối số khác với các giá trị mà thông số nhận được, nó là các giá trị thực sự được truyền vào3. chức năng mũi tênHàm mũi tên (hàm mũi tên) là một cách viết khác rút gọn hơn cho hàm, được giới thiệu từ phiên bản ES6. Ví dụ bên dưới, 3 hàm tương tự nhau nhưng có cách viết khác nhau 7Cách 2 là cú pháp chuẩn của hàm mũi tên, dạng 00, với dấu 01 là dấu mũi tên (mũi tên)Rút gọn trả về Cách 3 Rút gọn lệnh return. If body function only have a command return, then could Rút gọn theo cách bỏ trích dẫn {} Rút gọn một lệnh If body function only have a command (not must be return), then could reject quote {} 8Chú ý, if only have a command but is return, then must bỏ return as way 3 at on. If to return always will have error 9Rút gọn tham số If function has 1 tham số, thì cú pháp () có thể bỏ qua 0If no tham số nào, then must keep cặp (), không được bỏ qua 1D. Gọi, áp dụng và đóng cửa1. Phương thức gọiMỗi hàm đều có một phương thức với tên 02, dùng để truyền một đối tượng vào hàm đó. Khi đối tượng vào hàm được gọi với 02, thì đối tượng sẽ biến thành đối tượng this. Hàm sử dụng cái này, thực chất là sử dụng đối tượng được truyền vàoVí dụ như đoạn mã sau 2Mã trên định nghĩa hai đối tượng
Bạn sẽ đặt câu hỏi "tại sao không truyền thẳng đối tượng vào phương thức như một tham số?". Thực hiện câu hỏi đó hoàn toàn có lý do, và mã như vậy chúng ta sẽ trông giống như sau 3Hai đoạn mã trên tương tự nhau, cho ra kết quả giống nhau Tai sao goi? Sự khác biệt nằm ở vị trí bối cảnh của chức năng thay đổi. Khi gọi hàm với 02 và một đối tượng, thì giống như việc đưa hàm vào trong đối tượng kia. Đối với hàm là phương thức, thì chủ sở hữu của phương thức bị thay đổi thành đối tượng được gọi bởi 02. Ví dụ như mã trên thực tế như sau 4Nói chung phần này hơi ảo, và thực tế không sử dụng nhiều đối tượng như cách truyền thông như tham số Cuộc gọi và thông số Chức năng được gọi với 02 có thể có thêm các thông số khác 5Lúc này khi gọi 02 thì truyền đúng theo tham số, nhưng đối số đầu tiên phải là đối tượng được truyền vào. Các đối số thứ 2 sẽ thành tham số 1, đối số 3 thành tham số 2,. cứ như vậy. Nghĩa là đối số đầu tiên bị mất và trở thành 13 trong hàmAs on code on, then when call 02 đối số 06 thành 13 in function 22, chuỗi đối số thứ 2 "Phan so test" được truyền vào tham số thứ nhất 232. Áp dụng phương phápPhương pháp 24 tương tự như 02, nhưng sự khác biệt ở các vị trí tham số bổ sung được truyền dưới dạng mảng 6Hàm được 24 vẫn giữ nguyên các tham số riêng lẻ, nhưng khi gọi với 24 như trên thì truyền vào là mảng. Từng phần tử của mảng này sẽ chuyển vào từng tham số tương ứng để phù hợpES6 cung cấp một cách khác là toán tử trải rộng tương tự như 24, nhưng không phổ biến lắmSử dụng 24 rất tiện lợi khi các đối tượng truyền vào có dạng mảng, sẽ dễ dàng hơn trong các thao tác3. Gọi, áp dụng trong chế độ nghiêm ngặtThông thường, nếu gọi 02 hoặc 24 với đối số đầu tiên không phải đối tượng hoặc không truyền đối tượng, thì khi vào chức năng được gọi 13 sẽ là cửa sổ đối tượngNhưng trong chế độ nghiêm ngặt, điều này bị cấm. Khi sử dụng 02 hoặc 24, đối số đầu tiên bắt buộc phải là đối tượng và không được bỏ quaE. Khép kín1. Tổng quanClosure là một trong những khái niệm đáng nhớ nhất trong JS, và rất khó hiểu và định nghĩa chính xác nó là gì
Theo định nghĩa của MDN về việc đóng cửa, thì có thể hiểu như sau (tạm dịch)
Có vẻ như khái niệm đóng vẫn còn khá đối tượng, nhưng đừng lo. Vui lòng đi vào đoạn mã ví dụ để hiểu rõ hơn 7Bên trên là cấu trúc cơ bản của một bao đóng. Theo định nghĩa phía trên, chúng ta áp dụng vào mã để hiểu rõ hơn Ở đây hàm 35 được đóng gói lại bên trong hàm 36. Chức năng 35 này, chức năng tương tự khác, có thể truy cập vào các 38 (biến cục bộ của chính nó), hoặc 39 (biến toàn cục của chương trình). Điểm đặc biệt là 35 cũng có thể truy cập vào 41, vì nó liên tục tham chiếu đến hàm 42, là nơi nó được tạo raĐóng cửa & phạm vi Khi nhắc tới việc đóng phải nhắc tới phạm vi. Như phân tích ở trên, chức năng thường chỉ có hai phạm vi, nhưng đóng lại tạo ra tới 3 phạm vi. Chính phạm vi mới này được tạo ra nên các tính chất đặc biệt của việc đóng cửa Đặc điểm đóng cửa Một lần đóng cửa có hai đặc điểm sau
2. Constructor a closureClosure has cấu trúc bao gồm 2 phần
Ví dụ như sau là một lần đóng cửa đầy đủ nhất 8Câu đố dành cho bạn đây. Hàm 36 phía trên được gọi mấy lần?Nếu câu trả lời là 3 hoặc 4 lần thì bạn nhầm rồi. Hàm 36 chỉ được gọi duy nhất một lần trong câu lệnh let, trong biểu thức hàm có dấu () nghĩa là chạy 36 một lầnBạn sẽ bảo "chạy 46 cũng giống như chạy 36 vì đã được gán vào rồi". Vâng, nhưng thứ được gán vào biến 48 ở đây không phải bản thân 36, mà là cái hàm "bé bé xinh xinh" được 36 return ra đấy. Chính là thằng ml 35 đấy. Để phân tích kỹ năng hơn câu lệnh 52. Đầu tiên, 36 sẽ chạy trước vì có tự gọi (). Kết quả 36 trả về tham chiếu của anh 35. Biến 48 phải nhận tham chiếu này, và kể từ đó 46 là 35Mã trên nên viết lại với những nhận xét như sau cho dễ hiểu 9Vâng, đó chính là cách hoạt động của việc đóng cửa Câu hỏi 1 Câu hỏi đầu tiên được đặt ra ở đây là "mã trên liên quan còn gì để đóng?" Hãy nhớ lại phạm vi đặc điểm của một lần đóng cửa
Rồi, bây giờ quay lại mã phía trên. Để thực hiện 2 đặc điểm trên, đơn giản chỉ cần khai báo các biến bên trong 36 0Như đã phân tích, thì 36 chỉ chạy 1 lần. Mục đích của lần chạy duy nhất này là khởi tạo giá trị cho biến 61. Và các lần gọi tiếp theo thì không phải gọi 36 mà trở thành gọi 35Hàm 35 cùng cấp với biến 61 để chúng có thể truy cập lẫn nhau. Và bắt đầu ở đây, hai đặc điểm của việc đóng cửa được thực thiĐặc điểm 1. 35 có thể chạy nhiều lần, nhưng giá trị của 61 vẫn được giữ lại, vì JS chỉ xóa những gì khai báo trong 35 khi nó chạy xong, 61 khai báo bên ngoài không nên bị xóa khi 35 chạy xongĐặc điểm 2. 35 và 61 cùng thuộc về 36, là local var của 36 nên các đối tượng bên ngoài không truy cập được. Nghĩa là chỉ trong 36, đồng nghĩa với việc chỉ các thành viên của close mới có thể truy cập lẫn nhauÀ, bắt đầu thấy liên quan chưa Câu hỏi 2 Câu hỏi thứ 2 liên quan đến câu hỏi 1 mà các bạn có thể nghĩ đến, là "làm sao biến bên ngoài có thể được giữ lại khi bên ngoài chỉ thực hiện một lần rồi thôi?" Thực ra 36 chưa bao giờ bị dừng lại cả, do đó các biến khai báo trong hàm 36 vẫn giữ nguyên giá trị, không bị xóa đi. Only to when 35 or 46 not also used nữa thì JS newloại bỏ luôn 36Có thể hiểu như nếu còn 35 thì 36 đang ở trạng thái chờ. Chờ cho tới khi không còn dùng tới 35 nữa thì 36 mới kết thúcNếu đi sâu vào thêm nữa thì nó liên quan đến cách JS thực thi các hàm trong ngữ cảnh thực thi, rồi gọi ngăn xếp đủ thứ nên dừng lại ở đây 3. Rút gọn đóng cửaClosure as example on vẫn còn khá dài, nên được rút gọn lại như sau 1Phiên bản đầu tiên Rút gọn đi hàm 35 mà trực tiếp trả về một hàm ẩn danh luôn, đỡ phải viết nhiềuTiếp theo, chúng ta thay vì viết hàm 36 như bình thường (dạng 87) nên đổi lại biểu thức hàm viết dạng và để nó tự chạy (tự gọi) luôn 24. Thí dụVí dụ về việc đóng cửa của mình có thể không rõ nghĩa lắm, tuy có phân tích khá chi tiết nhưng thực tế nó không có ý nghĩa trong thực tế Do đó, mình khuyến khích các bạn tìm hiểu thêm một số ví dụ về sự đóng cửa khác nữa, để nói rõ hơn về sự đóng cửa vì đây là một khái niệm cực kỳ quan trọng |