PEAN Stack Day 1 - IIFE, Scope và Closure
Mở đầu series mới về PEAN stack, mình sẽ cùng các bạn tìm hiểu 3 khái niệm hay ho trong Javascript: IIFE, Scope, và Closure. Đây là những khái niệm mà mình tin rằng mọi javascript developer cần nắm vững!
1. IIFE - Immediately Invoked Function Expressions
1.1. Khái niệm
Các bạn đã bao giờ tự hỏi, làm cách nào tạo một function và tự động thực thi nó ngay lập tức không? Đó chính là IIFE!
IIFE là cách mà chúng ta có thể tạo một function và chạy nó ngay lập tức mà không cần gọi tên function đó.
Ví dụ:
(function() {
console.log("Đây là IIFE!"); // Đây là IIFE!
})();
1.2. Ứng dụng
Một ứng dụng thực sự hữu ích của IIFE là giúp chúng ta tạo ra "private variables" trong Javascript. Với IIFE, biến bên trong function sẽ không bị ảnh hưởng bởi các biến bên ngoài.
Ví dụ:
var name = "IT VN Chất";
(function() {
var name = "Private World!";
console.log(name); // Private World!
})();
console.log(name); // IT VN Chất
2. Scope
2.1. Khái niệm
Scope giúp chúng ta kiểm soát và quản lý phạm vi hoạt động của biến. Trong Javascript, chúng ta có 2 loại scope chính là: Global Scope và Local Scope.
2.2. Ứng dụng
-
Global Scope: Khi một biến được khai báo bên ngoài function.
var globalVar = "Tôi là global!"; function checkScope() { console.log(globalVar); // Tôi là global! } checkScope();
-
Local Scope: Khi một biến được khai báo bên trong function.
function checkScope() { var localVar = "Tôi là local!"; console.log(localVar); // Tôi là local! } checkScope(); console.log(localVar); // Error: localVar is not defined
3. Closure
3.1. Khái niệm
Closure là một function được tạo ra bởi một function khác. Đặc điểm nổi bật là closure có thể truy cập vào các biến của function cha của nó.
3.2. Ứng dụng
Closure giúp chúng ta tạo ra các private methods hay variables trong Javascript.
Ví dụ:
function makeCounter() {
var count = 0;
return function() {
return count++;
};
}
var counter = makeCounter();
console.log(counter()); // 0
console.log(counter()); // 1
Trong ví dụ trên, function bên trong truy cập và tăng biến count
mặc dù nó được định nghĩa ngoài cùng. Điều này chỉ có thể xảy ra nhờ Closure.
Một số ví dụ khác
IIFE (Immediately Invoked Function Expressions)
Ví dụ 1: Sử dụng IIFE để khởi tạo một plugin
Giả sử bạn đang viết một plugin jQuery và muốn đảm bảo không ảnh hưởng tới các biến hoặc hàm ngoài.
(function($) {
// Bên trong đây, $ sẽ là jQuery
$(document).ready(function() {
// Mã của plugin
});
})(jQuery);
Ở đây, chúng ta sử dụng IIFE để tránh xung đột giữa jQuery và các thư viện khác. $
bên trong IIFE sẽ luôn ám chỉ jQuery.
Ví dụ 2: Khởi tạo một biến chỉ đọc
var CONSTANTS = (function() {
var secretKey = "12345";
return {
API_URL: "https://myapi.com",
getSecretKey: function() {
return secretKey;
}
};
})();
console.log(CONSTANTS.API_URL); // https://myapi.com
console.log(CONSTANTS.getSecretKey()); // 12345
Trong ví dụ này, IIFE giúp tạo ra một object CONSTANTS
mà người dùng chỉ có thể truy cập thông qua các phương thức được cung cấp.
Scope
Ví dụ 1: Sử dụng block scope để xử lý dữ liệu
{
let temporaryData = "data";
// Xử lý temporaryData
console.log(temporaryData); // "data"
}
//console.log(temporaryData); // Lỗi: temporaryData không tồn tại
Ở ví dụ này, temporaryData
chỉ tồn tại trong block {}
, giúp tránh làm ô nhiễm global scope.
Ví dụ 2: Sử dụng function scope để tạo biến riêng biệt
function processData(data) {
var processed = "Processed: " + data;
return processed;
}
console.log(processData("myData")); // Processed: myData
//console.log(processed); // Lỗi: processed không tồn tại
Ở đây, biến processed
chỉ tồn tại trong hàm processData
, giúp tách biệt logic xử lý.
Closure
Ví dụ 1: Tạo một hàm tăng giá trị
function createIncrementer() {
let count = 0;
return function() {
return count++;
};
}
const increment = createIncrementer();
console.log(increment()); // 0
console.log(increment()); // 1
Hàm createIncrementer
trả về một closure giữ lại trạng thái của count
mỗi khi gọi hàm increment
.
Ví dụ 2: Ẩn dữ liệu bên trong một module
var Module = (function() {
var privateData = "I am private";
return {
getPrivateData: function() {
return privateData;
}
};
})();
console.log(Module.getPrivateData()); // "I am private"
//console.log(Module.privateData); // undefined
Sử dụng closure, chúng ta có thể tạo ra các module với dữ liệu và phương thức riêng tư. Trong ví dụ trên, privateData
chỉ có thể truy cập thông qua hàm getPrivateData
.
English version
Hey there! Let's dive into a new series about the PEAN stack. Today, we'll explore three cool ideas in JavaScript: IIFE, Scope, and Closure. These are concepts that I believe every JavaScript developer should get a good grasp on.
1. IIFE - Immediately Invoked Function Expressions
1.1. What's this?
Have you ever wondered how to create a function and make it run right away without calling its name? Well, that's where IIFE comes in!
IIFE is a way to create a function and run it immediately without needing to call its name.
For example:
(function() {
console.log("This is an IIFE!"); // This is an IIFE!
})();
1.2. Where it shines
One super useful thing about IIFE is that it helps us make "private variables" in JavaScript. With IIFE, variables inside the function won't be affected by variables outside of it.
For instance:
var name = "Awesome IT World";
(function() {
var name = "Private Galaxy!";
console.log(name); // Private Galaxy!
})();
console.log(name); // Awesome IT World
2. Scope
2.1. Scope? What's that?
Scope helps us control and manage where variables work. In JavaScript, we have two main types of scope: Global Scope and Local Scope.
2.2. Where to use them
-
Global Scope: When a variable is declared outside a function.
var globalVar = "I am global!"; function checkScope() { console.log(globalVar); // I am global! } checkScope();
-
Local Scope: When a variable is declared inside a function.
function checkScope() { var localVar = "I am local!"; console.log(localVar); // I am local! } checkScope(); console.log(localVar); // Error: localVar is not defined
3. Closure
3.1. What's Closure?
Closure is a function that's created by another function. The special thing about closure is that it can access variables from its parent function.
3.2. Where's it handy?
Closure helps us make private methods or variables in JavaScript.
For example:
function makeCounter() {
var count = 0;
return function() {
return count++;
};
}
var counter = makeCounter();
console.log(counter()); // 0
console.log(counter()); // 1
In this example, the inner function accesses and increases the count
variable even though it's defined outside. This magic happens thanks to Closure.
Some more examples
IIFE (Immediately Invoked Function Expressions)
Example 1: Using IIFE to set up a plugin
Let's say you're crafting a jQuery plugin and want to make sure it doesn't mess with other variables or functions.
(function($) {
// Inside here, $ means jQuery
$(document).ready(function() {
// Plugin code
});
})(jQuery);
Here, we use IIFE to prevent conflicts between jQuery and other libraries. The $
inside the IIFE always refers to jQuery.
Example 2: Creating a read-only variable
var CONSTANTS = (function() {
var secretKey = "12345";
return {
API_URL: "https://myapi.com",
getSecretKey: function() {
return secretKey;
}
};
})();
console.log(CONSTANTS.API_URL); // https://myapi.com
console.log(CONSTANTS.getSecretKey()); // 12345
In this example, IIFE helps us create a CONSTANTS
object that users can only access through provided methods.
Scope
Example 1: Using block scope for data handling
{
let temporaryData = "data";
// Handle temporaryData
console.log(temporaryData); // "data"
}
//console.log(temporaryData); // Error: temporaryData doesn't exist
In this example, temporaryData
only exists within the curly braces {}
, avoiding polluting the global scope.
Example 2: Using function scope to isolate variables
function processData(data) {
var processed = "Processed: " + data;
return processed;
}
console.log(processData("myData")); // Processed: myData
//console.log(processed); // Error: processed doesn't exist
Here, the processed
variable only exists within the processData
function, keeping the processing logic separate.
Closure
Example 1: Creating an increment function
function createIncrementer() {
let count = 0;
return function() {
return count++;
};
}
const increment = createIncrementer();
console.log(increment()); // 0
console.log(increment()); // 1
The createIncrementer
function returns a closure that holds onto the state of count
each time increment
is called.
Example 2: Hiding data inside a module
var Module = (function() {
var privateData = "I am private";
return {
getPrivateData: function() {
return privateData;
}
};
})();
console.log(Module.getPrivateData()); // "I am private"
//console.log(Module.privateData); // undefined
Using closure, we can create modules with private data and methods. In the example above, privateData
can only be accessed through getPrivateData
function.
日本語版
よし、新しいシリーズのスタートです!PEANスタックに関する新しいシリーズを始めます。今回はJavaScriptの中で興味深い3つの概念、IIFE(イーフィー)、スコープ、そしてクロージャについて一緒に学びましょう。これらの概念は、すべてのJavaScript開発者がしっかり理解しておくべきものですよ!
1. IIFE - 即時実行関数式
1.1. 概念
みんな、一度は「関数を作って、それをすぐに実行する方法ってどうやるの?」って考えたことがありますよね?それがIIFEです!
IIFE(イーフィー) とは、関数を作成し、その関数の名前を呼び出さずにすぐに実行する方法なんです。
例えば:
(function() {
console.log("これがIIFEだよ!"); // これがIIFEだよ!
})();
1.2. 用途
IIFEの本当に役立つ用途の一つは、JavaScript内で「プライベート変数」を作成することです。IIFEを使うと、関数内の変数は外部の変数に影響を受けないようになります。
例えば:
var name = "すごいITエンジニア";
(function() {
var name = "プライベートワールド!";
console.log(name); // プライベートワールド!
})();
console.log(name); // すごいITエンジニア
2. スコープ
2.1. 概念
スコープは、変数の活動範囲を制御し管理するのに役立ちます。JavaScriptには、グローバルスコープ と ローカルスコープ の2つの主要なスコープがあります。
2.2. 用途
-
グローバルスコープ: 関数の外で変数が宣言されている場合。
var globalVar = "僕はグローバルだよ!"; function checkScope() { console.log(globalVar); // 僕はグローバルだよ! } checkScope();
-
ローカルスコープ: 関数内で変数が宣言されている場合。
function checkScope() { var localVar = "僕はローカルだよ!"; console.log(localVar); // 僕はローカルだよ! } checkScope(); console.log(localVar); // エラー:localVarは未定義です
3. クロージャ
3.1. 概念
クロージャ とは、他の関数から作成される関数のことです。特筆すべき特徴は、クロージャがその親関数の変数にアクセスできることです。
3.2. 用途
クロージャを使うことで、JavaScript内でプライベートメソッドや変数を作成することができます。
例えば:
function makeCounter() {
var count = 0;
return function() {
return count++;
};
}
var counter = makeCounter();
console.log(counter()); // 0
console.log(counter()); // 1
上記の例では、外側で定義された関数内の関数が count
変数にアクセスして増やしています。これはクロージャを使うことで可能になります。
他の例も見てみよう
IIFE(即時実行関数式)
例1:プラグインを初期化するためにIIFEを使用
jQueryのプラグインを作成しているとしましょう。外部の変数や関数に影響を与えないようにしたい場合、IIFEが役立ちます。
(function($) {
// ここで $ は jQuery です
$(document).ready(function() {
// プラグインのコード
});
})(jQuery);
ここでは、IIFEを使ってjQueryと他のライブラリとの衝突を避けています。IIFE内の $
は常にjQueryを指します。
例2:読み取り専用の変数を初期化
var CONSTANTS = (function() {
var secretKey = "12345";
return {
API_URL: "https://myapi.com",
getSecretKey: function() {
return secretKey;
}
};
})();
console.log(CONSTANTS.API_URL); // https://myapi.com
console.log(CONSTANTS.getSecretKey()); // 12345
この例では、IIFEを使って CONSTANTS
オブジェクトを作成し、ユーザーが提供されたメソッドを通じてのみアクセスできるようにしています。
スコープ
例1:ブロックスコープを使用してデータを処理
{
let temporaryData = "データ";
// temporaryDataの処理
console.log(temporaryData); // "データ"
}
//console.log(temporaryData); // エラー:temporaryDataは存在しません
この例では、temporaryData
は {}
ブロック内だけで存在し、グローバルスコープの混乱を防ぎます。
例2:関数スコープを使用して個別の変数を作成
function processData(data) {
var processed = "処理済み:" + data;
return processed;
}
console.log(processData("私のデータ")); // 処理済み:私のデータ
//console.log(processed); // エラー:processedは存在しません
ここでは、変数 processed
は関数 processData
内でのみ存在し、処理ロジックを隔離するのに役立っています。
クロージャ
例1:値を増やす関数を作成
function createIncrementer() {
let count = 0;
return function() {
return count++;
};
}
const increment = createIncrementer();
console.log(increment()); // 0
console.log(increment()); // 1
関数 createIncrementer
は、毎回 increment
関数を呼び出すたびに count
の状態を保持するクロージャを返します。
例2:モジュール内のデータを隠蔽
var Module = (function() {
var privateData = "私はプライベートです";
return {
getPrivateData: function() {
return privateData;
}
};
})();
console.log(Module.getPrivateData()); // "私はプライベートです"
//console.log(Module.privateData); // 未定義
クロージャを使って、データとプライベートメソッドを持つモジュールを作成できます。上の例では、privateData
には getPrivateData
関数を通じてしかアクセスできません。
Mình hy vọng bạn thích bài viết này và học thêm được điều gì đó mới.
Donate mình một ly cafe hoặc 1 cây bút bi để mình có thêm động lực cho ra nhiều bài viết hay và chất lượng hơn trong tương lai nhé. À mà nếu bạn có bất kỳ câu hỏi nào thì đừng ngại comment hoặc liên hệ mình qua: Zalo - 0374226770 hoặc Facebook. Mình xin cảm ơn.
Momo: NGUYỄN ANH TUẤN - 0374226770
TPBank: NGUYỄN ANH TUẤN - 0374226770 (hoặc 01681423001)
All rights reserved