!function () {}(); 自執行匿名函式 Self-Executing Anonymous Function
https://stackoverflow.com/questions/3755606/what-does-the-exclamation-mark-do-before-the-function
JavaScript syntax 101. Here is afunction declaration:
function foo() {}
Note that there's no semicolon: this is just a functiondeclaration. You would need an invocation,foo()
, to actually run the function.
Now, when we add the seemingly innocuous exclamation mark:!function foo() {}
The!
alone doesn't invoke the function, of course, but we can now put()
at the end:!function foo() {}()
which has higher precedence than!
and instantly calls the function.
So what the author is doing is saving a byte per function expression; a more readable way of writing it would be this:
(function(){})();
Lastly,!
makes the expression return true. This is because by default all immediately invoked function expressions (IIFE) returnundefined
, which leaves us with!undefined
which istrue
. Not particularly useful.
https://stackoverflow.com/questions/9267289/what-does-function-in-javascript-mean
Self-Executing Anonymous Function - MDN Web Docs Glossary: Definitions of Web-related terms | MDN https://developer.mozilla.org/en-US/docs/Glossary/Self-Executing_Anonymous_Function
https://developer.mozilla.org/en-US/docs/Glossary/IIFE
IIFE(立即呼叫函式表示式)
IIFE( 立即呼叫函式表示式)是一個在定義時就會立即執行的JavaScript函式。
(function () {
statements
})();
這是一個被稱為自執行匿名函式的設計模式,主要包含兩部分。第一部分是包圍在圓括號運算子
()
裡的一個匿名函式,這個匿名函式擁有獨立的詞法作用域。這不僅避免了外界訪問此 IIFE 中的變數,而且又不會汙染全域性作用域。
第二部分再一次使用()
建立了一個立即執行函式表示式,JavaScript 引擎到此將直接執行函式。
示例
當函式變成立即執行的函式表示式時,表示式中的變數不能從外部訪問。
(function () {
var name = "Barry";
})();
// 無法從外部訪問變數 name
name // 丟擲錯誤:"Uncaught ReferenceError: name is not defined"
將 IIFE 分配給一個變數,不是儲存 IIFE 本身,而是儲存IIFE 執行後返回的結果。
var result = (function () {
var name = "Barry";
return name;
})();
// IIFE 執行後返回的結果:
result; // "Barry"
IIFE
AnIIFE(Immediately Invoked Function Expression)is aJavaScriptfunctionthat runs as soon as it is defined. The name IIFE is promoted by Ben Alman inhis blog.
(function () {
statements
})();
It is a design pattern which is also known as aSelf-Executing Anonymous Functionand contains two major parts:
- The first is the anonymous function with lexical scope enclosed within the
Grouping Operator
()
. This prevents accessing variables within the IIFE idiom as well as polluting the global scope. - The second part creates the immediately invoked function expression
()
through which the JavaScript engine will directly interpret the function.
Use cases
Avoid polluting the global namespace
Because our application could include many functions and global variables from different source files, it's important to limit the number of global variables. If we have some initiation code that we don't need to use again, we could use the IIFE pattern. As we will not reuse the code again, using IIFE in this case is better than using a function declaration or a function expression.
(function () {
// some initiation code
let firstVariable;
let secondVariable;
})();
// firstVariable and secondVariable will be discarded after the function is executed.
The module pattern
We would also use IIFE to create private and public variables and methods. For a more sophisticated use of the module pattern and other use of IIFE, you could see the book Learning JavaScript Design Patterns by Addy Osmani.
const makeWithdraw = balance => (function(copyBalance) {
let balance = copyBalance; // This variable is private
let doBadThings = function() {
console.log("I will do bad things with your money");
};
doBadThings();
return {
withdraw: function(amount) {
if (balance >= amount) {
balance -= amount;
return balance;
} else {
return "Insufficient money";
}
},
}
})(balance);
const firstAccount = makeWithdraw(100); // "I will do bad things with your money"
console.log(firstAccount.balance); // undefined
console.log(firstAccount.withdraw(20)); // 80
console.log(firstAccount.withdraw(30)); // 50
console.log(firstAccount.doBadThings); // undefined, this method is private
const secondAccount = makeWithdraw(20); // "I will do bad things with your money"
secondAccount.withdraw(30); // "Insufficient money"
secondAccount.withdraw(20); // 0
For loop with var before ES6
We could see the following use of IIFE in some old code, before the introduction of the statementsletandconstinES6and the block scope. With the statementvar, we have only function scopes and the global scope. Suppose we want to create 2 buttons with the texts Button 0 and Button 1 and we click them, we would like them to alert 0 and 1. The following code doesn't work:
for (var i = 0; i < 2; i++) {
const button = document.createElement("button");
button.innerText = "Button " + i;
button.onclick = function () {
alert(i);
};
document.body.appendChild(button);
}
console.log(i); // 2
When clicked, both Button 0 and Button 1 alert 2 becausei
is global, with the last value 2. To fix this problem before ES6, we could use the IIFE pattern:
for (var i = 0; i < 2; i++) {
const button = document.createElement("button");
button.innerText = "Button " + i;
button.onclick = (function (copyOfI) {
return function() {alert(copyOfI);};
})(i);
document.body.appendChild(button);
}
console.log(i); // 2
When clicked, Buttons 0 and 1 alert 0 and 1. The variablei
is globally defined. Using the statementlet, we could simply do:
for (let i = 0;
i < 2; i++) {
const button = document.createElement("button");
button.innerText = "Button " + i;
button.onclick = function () {
alert(i);
};
document.body.appendChild(button);
}
console.log(i); // Uncaught ReferenceError: i is not defined.
When clicked, these buttons alert 0 and 1.
Self–invoking function in JavaScript? https://www.tutorialspoint.com/self-invoking-function-in-javascript
The self-invoking function in JavaScript are known as Immediately Invoked Function Expressions (IIFE). Immediately Invoked Function Expressions (IIFE) is a JavaScript function that executes immediately after it has been defined so there is no need to manually invoke IIFE.
Following is the code for self-invoking function (IIFE) in JavaScript −
Example
<!DOCTYPE html>
<html lang="javascript:void(0);en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
.sample {
font-size: 18px;
font-weight: 500;
}
</style>
</head>
<body>
<h1>JavaScript Immediately Invoked Function Expressions (IIFE)</h1>
<div class="sample"></div>
<script>
let sampleEle = document.querySelector(".sample");
(function () {
sampleEle.innerHTML = "This code is invoked immediately as soon as it is defined";
})();
</script>
</body>
</html>
Output
The above code will produce the following output −