JavaScriptã®ã¯ããŒãžã£ãå®è·µçãªäŸãéããŠæ¢æ±ãããã®æ©èœãšãœãããŠã§ã¢éçºã«ãããå®éã®å¿çšãçè§£ããŸãã
JavaScriptã®ã¯ããŒãžã£ïŒå®è·µçãªäŸã§ãããããã解説
ã¯ããŒãžã£ã¯JavaScriptã«ãããåºæ¬çãªæŠå¿µã§ãããããããã¬ãã«ã®éçºè ã«ãšã£ãŠæ··ä¹±ã®å ãšãªãããšããããããŸããã¯ããŒãžã£ãçè§£ããããšã¯ãå¹ççã§ä¿å®ãããããå®å šãªã³ãŒããæžãäžã§éåžžã«éèŠã§ãããã®å æ¬çãªã¬ã€ãã§ã¯ãå®è·µçãªäŸãçšããŠã¯ããŒãžã£ããããããã解説ãããã®å®éã®å¿çšäŸã瀺ããŸãã
ã¯ããŒãžã£ãšã¯ïŒ
ç°¡åã«èšããšãã¯ããŒãžã£ãšã¯ã颿°ãšãã®é¢æ°ã宣èšãããã¬ãã·ã«ã«ç°å¢ã®çµã¿åããã§ããããã¯ãã¯ããŒãžã£ã䜿çšãããšã颿°ã¯å€åŽã®é¢æ°ãå®è¡ãçµäºããåŸã§ããåšå²ã®ã¹ã³ãŒããã倿°ã«ã¢ã¯ã»ã¹ã§ããããšãæå³ããŸããå åŽã®é¢æ°ãèªåã®ç°å¢ããèšæ¶ããŠããããšèãããšããã§ãããã
ãããæ¬åœã«çè§£ããããã«ãäž»èŠãªã³ã³ããŒãã³ããåè§£ããŠã¿ãŸãããã
- 颿°ïŒã¯ããŒãžã£ã®äžéšã圢æããå åŽã®é¢æ°ã
- ã¬ãã·ã«ã«ç°å¢ïŒé¢æ°ã宣èšãããåšå²ã®ã¹ã³ãŒããããã«ã¯ã倿°ã颿°ããã®ä»ã®å®£èšãå«ãŸããŸãã
éæ³ãèµ·ããã®ã¯ãå åŽã®é¢æ°ããå€åŽã®é¢æ°ãè¿ãããåŸã§ãããã®ã¬ãã·ã«ã«ã¹ã³ãŒãå ã®å€æ°ãžã®ã¢ã¯ã»ã¹ãä¿æããŠããããã§ãããã®åäœã¯ãJavaScriptãã¹ã³ãŒããšã¡ã¢ãªç®¡çãåŠçããæ¹æ³ã®æ žå¿ã§ãã
ãªãã¯ããŒãžã£ã¯éèŠãªã®ãïŒ
ã¯ããŒãžã£ã¯åãªãçè«äžã®æŠå¿µã§ã¯ãããŸãããJavaScriptã«ãããå€ãã®äžè¬çãªããã°ã©ãã³ã°ãã¿ãŒã³ã«äžå¯æ¬ ã§ããã¯ããŒãžã£ã¯ã次ã®å©ç¹ãæäŸããŸãã
- ããŒã¿ã®ã«ãã»ã«åïŒã¯ããŒãžã£ã䜿çšãããšããã©ã€ããŒã倿°ãšã¡ãœãããäœæããå€éšããã®ã¢ã¯ã»ã¹ã倿ŽããããŒã¿ãä¿è·ã§ããŸãã
- ç¶æ ã®ä¿æïŒã¯ããŒãžã£ã¯é¢æ°åŒã³åºãéã§å€æ°ã®ç¶æ ãç¶æããŸããããã¯ãã«ãŠã³ã¿ãŒãã¿ã€ããŒãããã³ãã®ä»ã®ã¹ããŒããã«ãªã³ã³ããŒãã³ãã®äœæã«åœ¹ç«ã¡ãŸãã
- é«é颿°ïŒã¯ããŒãžã£ã¯ãé«é颿°ïŒä»ã®é¢æ°ãåŒæ°ãšããŠåã颿°ããŸãã¯é¢æ°ãè¿ã颿°ïŒãšçµã¿åãããŠäœ¿çšââãããããšãå€ãã匷åã§æè»ãªã³ãŒããå¯èœã«ããŸãã
- éåæJavaScriptïŒã¯ããŒãžã£ã¯ãã³ãŒã«ããã¯ãPromiseãªã©ã®éåææäœã®ç®¡çã«ãããŠéèŠãªåœ¹å²ãæãããŸãã
JavaScriptã®ã¯ããŒãžã£ã®å®è·µçãªäŸ
ã¯ããŒãžã£ãã©ã®ããã«æ©èœããå®éã®ã·ããªãªã§ã©ã®ããã«äœ¿çšã§ãããã説æããããã«ãããã€ãã®å®è·µçãªäŸãèŠãŠã¿ãŸãããã
äŸ1ïŒã·ã³ãã«ãªã«ãŠã³ã¿ãŒ
ãã®äŸã§ã¯ã颿°åŒã³åºãéã§ç¶æ ãç¶æããã«ãŠã³ã¿ãŒãäœæããããã«ãã¯ããŒãžã£ãã©ã®ããã«äœ¿çšã§ãããã瀺ããŸãã
function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
};
}
const increment = createCounter();
increment(); // Output: 1
increment(); // Output: 2
increment(); // Output: 3
解説ïŒ
createCounter()ã¯ã倿°countã宣èšããå€åŽã®é¢æ°ã§ããcountãã€ã³ã¯ãªã¡ã³ããããã®å€ããã°ã«èšé²ããå åŽã®é¢æ°ïŒãã®å Žåã¯ç¡å颿°ïŒãè¿ããŸãã- å
åŽã®é¢æ°ã¯ã
count倿°ã®ã¯ããŒãžã£ã圢æããŸãã createCounter()ãå®è¡ãçµäºããåŸã§ããå åŽã®é¢æ°ã¯count倿°ãžã®ã¢ã¯ã»ã¹ãä¿æããŸããincrement()ãåŒã³åºããã³ã«ãåãcount倿°ãã€ã³ã¯ãªã¡ã³ããããã¯ããŒãžã£ã®ç¶æ ãä¿æããæ©èœãå®èšŒãããŸãã
äŸ2ïŒãã©ã€ããŒã倿°ã«ããããŒã¿ã®ã«ãã»ã«å
ã¯ããŒãžã£ã䜿çšãããšããã©ã€ããŒã倿°ãäœæãã颿°å€éšããã®çŽæ¥ã¢ã¯ã»ã¹ã倿ŽããããŒã¿ãä¿è·ã§ããŸãã
function createBankAccount(initialBalance) {
let balance = initialBalance;
return {
deposit: function(amount) {
balance += amount;
return balance; //Returning for demonstration, could be void
},
withdraw: function(amount) {
if (amount <= balance) {
balance -= amount;
return balance; //Returning for demonstration, could be void
} else {
return "Insufficient funds.";
}
},
getBalance: function() {
return balance;
}
};
}
const account = createBankAccount(1000);
console.log(account.deposit(500)); // Output: 1500
console.log(account.withdraw(200)); // Output: 1300
console.log(account.getBalance()); // Output: 1300
// Trying to access balance directly will not work
// console.log(account.balance); // Output: undefined
解説ïŒ
createBankAccount()ã¯ãé éãåŒãåºããããã³æ®é«ãååŸããããã®ã¡ãœãããæã€éè¡å£åº§ãªããžã§ã¯ããäœæããŸããbalance倿°ã¯createBankAccount()ã®ã¹ã³ãŒãå ã§å®£èšãããå€éšããçŽæ¥ã¢ã¯ã»ã¹ã§ããŸãããdepositãwithdrawãããã³getBalanceã¡ãœããã¯ãbalance倿°ã®ã¯ããŒãžã£ã圢æããŸãã- ãããã®ã¡ãœããã¯
balance倿°ã«ã¢ã¯ã»ã¹ããŠå€æŽã§ããŸããã倿°èªäœã¯ãã©ã€ããŒãã®ãŸãŸã§ãã
äŸ3ïŒã«ãŒãã§`setTimeout`ãšã¯ããŒãžã£ã䜿çšãã
ã¯ããŒãžã£ã¯ãç¹ã«ã«ãŒãå
ã§ãsetTimeoutãªã©ã®éåææäœãæ±ãå Žåã«äžå¯æ¬ ã§ããã¯ããŒãžã£ããªãå ŽåãJavaScriptã®éåæçãªæ§è³ªã®ããã«ãäºæããªãåäœãçºçããå¯èœæ§ããããŸãã
for (var i = 1; i <= 5; i++) {
(function(j) {
setTimeout(function() {
console.log("Value of i: " + j);
}, j * 1000);
})(i);
}
// Output:
// Value of i: 1 (after 1 second)
// Value of i: 2 (after 2 seconds)
// Value of i: 3 (after 3 seconds)
// Value of i: 4 (after 4 seconds)
// Value of i: 5 (after 5 seconds)
解説ïŒ
- ã¯ããŒãžã£ïŒå³æå®è¡é¢æ°åŒããŸãã¯IIFEïŒããªãå Žåããã¹ãŠã®
setTimeoutã³ãŒã«ããã¯ã¯æçµçã«åãi倿°ãåç §ããã«ãŒããå®äºãããš6ã®æçµå€ã«ãªããŸãã - IIFEã¯ã«ãŒãã®åå埩åŠçã«å¯ŸããŠæ°ããã¹ã³ãŒããäœæãã
jãã©ã¡ãŒã¿ãŒã«iã®çŸåšã®å€ããã£ããã£ããŸãã - å
setTimeoutã³ãŒã«ããã¯ã¯j倿°ã®ã¯ããŒãžã£ã圢æããåå埩åŠçã§iã®æ£ããå€ããã°ã«èšé²ããããã«ããŸãã
ã«ãŒãã§varã®ä»£ããã«letã䜿çšããããšãããã®åé¡ãä¿®æ£ããŸããletã¯åå埩åŠçã«å¯ŸããŠãããã¯ã¹ã³ãŒããäœæããããã§ãã
for (let i = 1; i <= 5; i++) {
setTimeout(function() {
console.log("Value of i: " + i);
}, i * 1000);
}
// Output (same as above):
// Value of i: 1 (after 1 second)
// Value of i: 2 (after 2 seconds)
// Value of i: 3 (after 3 seconds)
// Value of i: 4 (after 4 seconds)
// Value of i: 5 (after 5 seconds)
äŸ4ïŒã«ãªãŒåãšéšåé©çš
ã¯ããŒãžã£ã¯ãè€æ°ã®åŒæ°ãæã€é¢æ°ããããããåäžã®åŒæ°ãåã颿°ã®ã·ãŒã±ã³ã¹ã«å€æããããã«äœ¿çšãããææ³ã§ããã«ãªãŒåãšéšåé©çšã®åºæ¬ã§ãã
function multiply(a) {
return function(b) {
return function(c) {
return a * b * c;
};
};
}
const multiplyBy5 = multiply(5);
const multiplyBy5And2 = multiplyBy5(2);
console.log(multiplyBy5And2(3)); // Output: 30 (5 * 2 * 3)
解説ïŒ
multiplyã¯ãäžåºŠã«3ã€ã®åŒæ°ãåãã«ãªãŒåããã颿°ã§ãã- åå
åŽã®é¢æ°ã¯ããã®å€åŽã®ã¹ã³ãŒãïŒ
aãbïŒããã®å€æ°ã®ã¯ããŒãžã£ã圢æããŸãã multiplyBy5ã¯ããã§ã«aã5ã«èšå®ãããŠãã颿°ã§ããmultiplyBy5And2ã¯ããã§ã«aã5ã«èšå®ãããbã2ã«èšå®ãããŠãã颿°ã§ããmultiplyBy5And2(3)ã®æåŸã®åŒã³åºãã¯ãèšç®ãå®äºããçµæãè¿ããŸãã
äŸ5ïŒã¢ãžã¥ãŒã«ãã¿ãŒã³
ã¯ããŒãžã£ã¯ãã¢ãžã¥ãŒã«ãã¿ãŒã³ã§å€çšãããŠããŸããããã¯ãJavaScriptã³ãŒããç·šæããã³æ§é åããã¢ãžã¥ãŒã«æ§ãä¿é²ããååã®ç«¶åãé²ãã®ã«åœ¹ç«ã¡ãŸãã
const myModule = (function() {
let privateVariable = "Hello, world!";
function privateMethod() {
console.log(privateVariable);
}
return {
publicMethod: function() {
privateMethod();
},
publicProperty: "This is a public property."
};
})();
console.log(myModule.publicProperty); // Output: This is a public property.
myModule.publicMethod(); // Output: Hello, world!
// Trying to access privateVariable or privateMethod directly will not work
// console.log(myModule.privateVariable); // Output: undefined
// myModule.privateMethod(); // Output: TypeError: myModule.privateMethod is not a function
解説ïŒ
- IIFEã¯æ°ããã¹ã³ãŒããäœæãã
privateVariableãšprivateMethodãã«ãã»ã«åããŸãã - è¿ããããªããžã§ã¯ãã¯ã
publicMethodãšpublicPropertyã®ã¿ãå ¬éããŸãã publicMethodã¯privateMethodãšprivateVariableã®ã¯ããŒãžã£ã圢æããIIFEãå®è¡ãããåŸã§ããããã«ã¢ã¯ã»ã¹ã§ããããã«ããŸãã- ãã®ãã¿ãŒã³ã¯ããã©ã€ããŒãã¡ã³ããŒãšãããªãã¯ã¡ã³ããŒãæã€ã¢ãžã¥ãŒã«ã广çã«äœæããŸãã
ã¯ããŒãžã£ãšã¡ã¢ãªç®¡ç
ã¯ããŒãžã£ã¯åŒ·åã§ãããã¡ã¢ãªç®¡çã«å¯Ÿããæœåšçãªåœ±é¿ã«æ³šæããããšãéèŠã§ããã¯ããŒãžã£ã¯åšå²ã®ã¹ã³ãŒãããã®å€æ°ãžã®ã¢ã¯ã»ã¹ãä¿æãããããäžèŠã«ãªã£ãå Žåã§ãããããã®å€æ°ãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããªãããã«ããããšãã§ããŸããããã¯ãæ éã«åŠçããªããšãã¡ã¢ãªãªãŒã¯ã«ã€ãªããå¯èœæ§ããããŸãã
ã¡ã¢ãªãªãŒã¯ãåé¿ããã«ã¯ãäžèŠã«ãªã£ããšãã«ã¯ããŒãžã£å
ã®å€æ°ãžã®äžèŠãªåç
§ããã¹ãŠè§£é€ããŠãã ãããããã¯ã倿°ãnullã«èšå®ããããäžèŠãªã¯ããŒãžã£ã®äœæãåé¿ããããã«ã³ãŒããåæ§ç¯ããããšã§è¡ãããšãã§ããŸãã
é¿ããã¹ãäžè¬çãªã¯ããŒãžã£ã®ééã
- ã¬ãã·ã«ã«ã¹ã³ãŒããå¿ããïŒã¯ããŒãžã£ã¯ã*äœææã®*ç°å¢ããã£ããã£ããããšãåžžã«èŠããŠãããŠãã ãããã¯ããŒãžã£ãäœæãããåŸã«å€æ°ã倿Žãããå Žåãã¯ããŒãžã£ã¯ãããã®å€æŽãåæ ããŸãã
- äžèŠãªã¯ããŒãžã£ã®äœæïŒäžèŠãªå Žåã¯ã¯ããŒãžã£ã®äœæãé¿ããŠãã ãããããã©ãŒãã³ã¹ãšã¡ã¢ãªäœ¿çšéã«åœ±é¿ãäžããå¯èœæ§ãããããã§ãã
- 倿°ã®ãªãŒã¯ïŒã¯ããŒãžã£ã«ãã£ãŠãã£ããã£ããã倿°ã®æå¹æéã«æ³šæããã¡ã¢ãªãªãŒã¯ãé²ãããã«äžèŠã«ãªã£ãå Žåã¯è§£æŸãããŠããããšã確èªããŠãã ããã
çµè«
JavaScriptã®ã¯ããŒãžã£ã¯ãJavaScriptéçºè ãçè§£ãã¹ã匷åã§äžå¯æ¬ ãªæŠå¿µã§ããããŒã¿ã«ãã»ã«åãç¶æ ã®ä¿æãé«é颿°ãããã³éåæããã°ã©ãã³ã°ãå¯èœã«ããŸããã¯ããŒãžã£ã®ä»çµã¿ãšå¹æçãªäœ¿ç𿹿³ãçè§£ããããšã§ãããå¹ççã§ä¿å®ãããããå®å šãªã³ãŒããäœæã§ããŸãã
ãã®ã¬ã€ãã§ã¯ãå®è·µçãªäŸãçšããŠã¯ããŒãžã£ã®å æ¬çãªæŠèŠã説æããŸããããããã®äŸãç·Žç¿ããŠå®éšããããšã§ãã¯ããŒãžã£ã®çè§£ãæ·±ããããçç·ŽããJavaScriptéçºè ã«ãªãããšãã§ããŸãã
ããã«åŠç¿ããããã«
- Mozilla Developer NetworkïŒMDNïŒïŒã¯ããŒãžã£ - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
- You Don't Know JS: Scope & Closures by Kyle Simpson
- CodePenãJSFiddleã®ãããªãªã³ã©ã€ã³ã³ãŒãã£ã³ã°ãã©ãããã©ãŒã ã調ã¹ãŠãããŸããŸãªã¯ããŒãžã£ã®äŸã詊ããŠã¿ãŠãã ããã