Gọi hàm trong javascript
Javascript
230
javascript function
6
White

Đào Văn Hùng viết ngày 28/04/2018

Link gốc bài viết tại đây
Bài này mình tách ra từ bài viết trước

Trong JS, dấu () để gọi thực thi hàm.

1. Function Decleration

Function decleration là function được khởi tạo bằng phép gán = ; function có thể có tên hoặc không có tên.

VD:

var f = function() {
   console.log(5);
}

// hoặc
var f = function test(){
   console.log(5);
}

Function declereation không được hoisting(khác với function expression giải thích phía dưới)

console.log(a); // Lỗi vì a chưa được khai báo
console.log(f); // undefined vì f đã được khai báo phía dưới nhưng chưa được hoisting
f(); // Lỗi vì f chưa được hoisting nên không biết f đang là kiểu function

var f = function(){
  console.log(5);
}

2. Function Expression

Function expression là hàm được khai báo như thông thường, hàm này có tên
Ví dụ:

function f(){
   console.log(5);
}

Khác với function decleration, function expression được hoisting:

console.log(f); // trả về function f thay vì undefined vì nó đã được hoisting
f(); // 5

function f(){
   console.log(5);
}

3. Function Invocation (Gọi thực thi hàm)

Function Invocation xảy ra khi gọi một hàm nào đó bằng cách sử dụng dấu (). Cách gọi thực thi hàm như thế được gọi là Function Invocation Pattern.

Ví dụ:

var add = function(num1, num2) {
    console.log(num1 + num2);
}

add(2, 3); // 5

Xét ví dụ:

var createCallBack = function() { //First function
        console.log("Here is in first function");

        return function() { //Second function
            console.log("Here is in second function");

            return function() { //Third function
                console.log("Here is in third function");
            }
        }
    }

createCallBack;// caller 1
createCallBack();// caller 2
window.onload = createCallBack; // caller 3
window.onload = createCallBack(); // caller 4
window.onload = createCallBack()();// caller 5

Nhớ là gọi caller 1 tới caller 5 từng lượt một chứ không phải gọi cùng lúc như trên nhé
Theo bạn tương ứng với mỗi câu lệnh caller 1 -> caller 5 thì kết quả in ra console là gì?

Nếu bạn thử kiểm tra từng câu lệnh trên bằng trình duyệt thì hãy gọi từng câu lệnh một chứ đừng gọi cả 5 câu lệnh cùng lúc như trên vì js là xử lý bất đồng bộ (assynchronus) nên sẽ không in ra đúng thứ tự cho bạn đâu.

  • caller 1 sẽ chẳng in ra cho bạn cái gì cả, vì hàm createCallBack đã được gọi thực thi đâu.

  • caller 2 sẽ in ra cho bạn "Here is in first function"

  • caller 3 sẽ in ra cho bạn "Here is in first function". Nhiều người sẽ thắc mắc vì sao caller 1caller 3 trông giống nhau mà kết qủa lại khác nhau?
    caller 3 là hàm createCallBack được truyền vào dưới dạng callback của event (sự kiện trên trình duyệt) nên khi event đó (ở vd trên là window.onload) được trigger thì hàm callback truyền vào sẽ tự động được thực thi.

Mọi hàm callback được truyền vào event thì sẽ được tự động thực thi ngay khi event đó trigger.

  • caller 4 sẽ in ra 2 dòng "Here is in first function" và "Here is in second function". Như bạn thấy caller 4 chỉ là thêm dấu () vào sau caller 3, nghĩa là nó thực thi caller 3 xong rồi thực thi tiếp hàm mà caller 3 trả về (vd trên là second function)

  • caller 5 giải thích tương tự caller 4, kết qủa in ra là "Here is in first function", "Here is in second function" và "Here is in third function".

Thế còn thế này thì sao?:

var createCallBack = function() { //First function
        console.log("first function");

        return function() { //Second function
            console.log("second function");

            return function() { //Third function
                console.log("third function");
            }
        }
    }

window.onload = function() { createCallBack; }; // caller 6
window.onload = function() { createCallBack(); }; // caller 7

Nhắc lại là mọi hàm callback được truyền vào event thì sẽ được tự động thực thi ngay khi event đó trigger.

Nghĩa là 2 function caller 6caller 7 trên đều được thực thi ngay khi window load, thực thi ngay ở đây nghĩa là thực thi nội dung trong dấu {} của 2 function truyền vào cho event window.onload.

  • caller 6 sẽ không in ra cái gì cả vì hàm createCallBack không được gọi thực thi.

  • caller 7 sẽ in ra "first function" vì hàm createCallBack được gọi thực thi bằng cách thêm dấu ()

4. Constructor Invocation Pattern.

Constructor Invocation Pattern là cách gọi hàm bằng cách thêm từ khóa new phía trước.

Ví dụ:

var createCallBack = function() { //First function
        console.log("first function");

        return new function() { //Second function
            console.log("second function");

            return function() { //Third function
                console.log("third function");
            }
        }
    }

window.onload = createCallBack;

Ví dụ trên giống với ví dụ ở phía trên với lời gọi caller 3. Nhưng lời gọi này ở phía trên chỉ in ra "first function" còn ở ví dụ này là "first function" và "second function". Vì sao?

Câu trả lời nằm ở từ khóa new đặt trước second function.
Từ khóa new chứng tỏ second function đã được gọi thực thi ngay (Constructor Invocation Pattern).

Ví dụ trên có thể được viết lại như sau:

var createCallBack = function() { //First function
        console.log("first function");

        var secondFunction = function() { //Second function
            console.log("second function");

            return function() { //Third function
                console.log("third function");
            }
        }

        return secondFunction();
    }

window.onload = createCallBack;

Hàm được gọi bằng kỹ thuật Constructor Invocation Pattern (dùng từ khóa new) sẽ trả về:

  • Nếu hàm có return các kiểu đơn như number, string, boolean, null hoặc undefined thì giá trị trả về sẽ bị bỏ đi và trả về this (là object được tạo ra từ từ khóa new).

  • Nếu hàm có return là một object (là mọi thứ trừ các kiểu đơn), thì object này sẽ được return thay vì this.

Với ví dụ trên thì second function sẽ return third function.

5. function là callback của inline event handler

Ví dụ:

<button onclick=myFunction()>Click me</button>
<!-- Hoặc <button onclick="myFunction()">Click me</button> -->

<script>
function myFunction() {
  console.log(5);
}
</script>

Khác với giải thích ở trên, khi truyền vào callback cho inline event handler (onclick) thì thứ được truyền vào phải là một expression (câu lệnh thực thi) hay một lời gọi thực thi hàm (như trên) chứ không phải là một khai báo hàm. Tuy có dấu () được đặt vào ngay sau tên hàm nhưng ở thời điểm biên dịch, hàm vẫn chưa được thực thi. Chỉ khi nào event onclick được trigger thì hàm mới được thực thi.

Nó giống như bạn truyền vào onclick một đoạn mã textABC, khi event được trigger thì nó sẽ thực thi câu lệnh eval(textABC) (Xem thêm về eval tại đây)


Link tham khảo:
http://doctrina.org/Javascript-Function-Invocation-Patterns.html#fi
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Đào Văn Hùng

7 bài viết.
19 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
22 2
Học hỏi chính là kinh nghiệm. Những thứ khác chỉ là thông tin. Albert Einstein Link gốc bài viết tại (Link). Đối với những bạn lập trình...
Đào Văn Hùng viết 7 tháng trước
22 2
White
17 5
Nếu cho tôi 6 tiếng để đốn hạ một cái cây, tôi sẽ dành 4 tiếng đầu tiên để mài rìu. Abraham Lincoln Bạn có thể đọc bài gốc tại (Link) Khi bắt đ...
Đào Văn Hùng viết 7 tháng trước
17 5
White
16 0
Cuộc đời là đóa hoa mà tình yêu là mật ngọt. Victor Hugo Các bạn có thể đọc bài viết gốc tại (Link) 1. Nonblocking I/O Trong javascript, hầu ...
Đào Văn Hùng viết 6 tháng trước
16 0
Bài viết liên quan
White
41 8
Tăng sức mạnh cho javascript với lodash Lần này mình sẽ giới thiệu 1 thư viện javascript vô cùng bá đạo có tên là "lodash]1]", có thể nói nó là LI...
Huy Hoàng Phạm viết hơn 2 năm trước
41 8
White
24 8
Lâu không post gì muốn viết một bài dài dài về js cơ mà đau đầu quá viết mãi không xong, thôi post bài ngắn vậy :smiley: Lấy screen size ở đây tôi...
Hoàng Duy viết hơn 2 năm trước
24 8
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
7 bài viết.
19 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!