IIFE in JS
Tags: javascript, chamdev, iife
Published: 2021-06-22 16:06:23

Nếu các bạn có cơ hội đọc những code rất cũ hoặc đã từng maintain dự án dùng JS thuần thì chắc có lẽ đã gặp IIFE (Immediately Invoked Function Expression) và đã chắc đã có lần đặt câu hỏi tại sao lại dùng nó, nó được dùng với tác dụng gì??? Trong phần này chúng ta sẽ cùng tìm hiểu IIFE nhé.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5vttodi66uvu1nqrs45h.png)
<!-- wp:paragraph -->
<p>Tuần vừa rồi mình vướng một số chuyện lên không có time viết bài, nhưng thật ra là mình lười ^^, về quê thì toàn chơi thôi - thế cho nhẹ đầu. Nhưng từ tuần này mình lại ra bài đều nhé, cập nhật tình hình thời tiết là hôm nay nóng lắm 38 - 40 độ, không có điều hòa chắc không sống được mất.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>1. Mở đầu</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>IIFE là viết tắt của Immediately Invoked Function Expression, nó là một dạng viết Function trong JS và nó sẽ được chạy ngay sau khi nó được khởi tạo.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Dạng function này có rất nhiều lợi ích như: Sẽ làm block các biến global, đỡ tốn bộ nhớ (Vì khởi tạo cái là chạy luôn, sau đó sẽ được clean khỏi memory), sẽ không cần khởi tạo Function global tránh polluted (Ô nhiễm) Global namespace.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>2. Chi tiết</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":4} -->
<h4><strong>Syntax</strong></h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Trước khi nói đến IIFE chúng ta hãy xem một function bình thường được định nghĩa và được exucute như thế nào nhé.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function func() {
    // Do something
}

func();</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Và như vậy khi chúng ta khai báo function đồng thời lại vô tình gắn nó vào memory sau đó gọi lại, nó sẽ là rất hay nếu như chúng ta gọi lại hàm này và coi nó như một hàm Common, gọi đi gọi lại nhiều lần. Khi đó cách khai báo function như trên là rất hợp lý, tuy nhiên hãy giả sử trường hợp là chúng ta chỉ cần gọi hàm đó 1 lần và ngay sau khi mà window được load xong chẳng hạn thì sẽ cần bỏ hàm đó vào trong <code>$(document).ready()</code> hoặc <code>window.onload</code> trong hợp như này thì nên dùng IIFE để memory được nhẹ, cùng như window object tránh ô nhiễm. Tại sao mình lại nói đến 2 vấn đề này thì các bạn hãy theo dõi tiếp nhé.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Còn bây giờ hãy nhìn syntax của IIFE nhé.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="javascript" class="language-javascript">// 1
(function(params) {
    // Do something
})(paramsInput);

// 2
((params) => {
    // Do something
})(paramsInput);

// 3
;(function(params) {
    // Do something
})(paramsInput);

// 4
;((params) => {
    // Do something
})(paramsInput);

// 5
(function nameFunc(params) {
    // Do something
})(paramsInput);</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Như các bạn đã thấy ở trên chúng ta có một số cách để khai báo IIFE. Nhưng mình chia làm 2 loại chính, một loại có tên function và loại còn lại không có tên function.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>IIFE có thể viết mà không có tên function vì nó chỉ được chạy có một lần, tuy nhiên cũng có thể viết tên function trong trường hợp các bạn muốn đặt tên tường mình ra chút (more meaning). Và hãy để ý là không thể đặt tên cho Arrow function viết theo kiểu IIFE nhé. Và kiểu viết tên thì cũng không thể call lại được, nó cũng chỉ chạy 1 lần thôi, nó không thể gắn vào Window Object được.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Bên trên mình có viết kiểu 3 và 4 có bạn hỏi tại sao lại viết vậy, liệu có viết nhầm không? Mình xin trả lời là không nhé, vì trong trường hợp bạn nối 2 file lại với nhau (Dùng package với Grunt, Gulp, Webpack, ....) thì có thể file trước và file sau nó sẽ như thế này:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre title="file_1.js" class="wp-block-code"><code lang="javascript" class="language-javascript">function func() {
    // Do something
}</code></pre>
<!-- /wp:code -->

<!-- wp:code -->
<pre title="file_2.js" class="wp-block-code"><code lang="javascript" class="language-javascript">(function func() {
    // Do something
})()</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Sau khi chạy lệnh, concat các file js thành 1 dòng nó sẽ lỗi:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre title="bundle.js" class="wp-block-code"><code lang="javascript" class="language-javascript">function func(){}(function func() {})()</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Nên mới có trường hợp để tránh lỗi này nên chúng ta sẽ add thêm <code>;</code> vào đăng trước IIFE.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre title="" class="wp-block-code"><code lang="javascript" class="language-javascript">function func() {
    // Do something
}

;(function func() {
    // Do something
})()

// =>

function func(){};(function func() {})()</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Tương tự đối với việc dùng arrow function nhé.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4><strong>Nhẹ Memory và tránh gây ô nhiễm cho window object.</strong></h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Ở đây 2 ý này là một nhé, vì khi chúng ta khai báo một function thì chính function cũng đã được add vào Window Object, như vậy thì khai báo càng nhiều thì sẽ càng làm cho đối tượng này bị phình to ra và như vậy sẽ rất khó kiểm soát.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function func() {
    console.log("func");
}

window.func(); // func</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":4} -->
<h4><strong>Tại sao lên dùng IIFE.</strong></h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Với các đặc tính ở bên trên thì IIFE đang tỏ hết sức mạnh mẽ trong một số trường hợp với các phần logic mà chúng ta chỉ cần chạy 1 lần. Tuy nhiên cũng chính vì vậy nên nó không thể dùng lại ở những phần khác.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>3. Kết luận</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Đây là một dạng viết function không phải là mới, tuy nhiên các bạn có lẽ sẽ ít gặp và sẽ gặp nhiều hơn khi mà làm các dự án maintain hoặc những dự án code JS thuần.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Còn khi làm dự án mới hoặc có Framework thì có lẽ các bạn sẽ không thấy nó nữa, tuy nhiên cũng lên biết để hiểu thêm về JS, để nhỡ như có gặp nó thì cũng không bỡ ngỡ với nó.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>4. Tham khảo</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://www.javascripttutorial.net/javascript-immediately-invoked-function-expression-iife/"># JavaScript Immediately Invoked Function Expression</a><br><a href="https://developer.mozilla.org/en-US/docs/Glossary/IIFE"># IIFE</a><br><a href="https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174"># What is an IIFE in JavaScript?</a><br><a href="https://flaviocopes.com/javascript-iife/"># JavaScript Immediately-invoked Function Expressions (IIFE)</a></p>
<!-- /wp:paragraph -->