Home Web Front-end JS Tutorial In-depth understanding of JavaScript series (4) Immediately called function expression_javascript skills

In-depth understanding of JavaScript series (4) Immediately called function expression_javascript skills

May 16, 2016 pm 05:57 PM

Preface
When you learn JavaScript, you often encounter code for self-executing anonymous functions. Today we will mainly talk about self-execution.
Before we learn more about this, let’s talk about the name “self-execution”. The name of this function in this article may not be completely correct. It mainly depends on how individuals understand it, because some people say that it is called immediately. Some people say automatic execution, so you can choose a name according to your own understanding. However, I heard many people call it "self-execution", but the author said a lot later to convince everyone to call it "immediate call". function expression".
The original English address of this article: http://benalman.com/news/2010/11/immediately-invoked-function-expression/
What is self-execution?
In JavaScript, any function will create an execution context when it is executed, because the variables and functions declared for the function may only be inside the function. This context provides a simple way when calling the function. way to create free variables or private subfunctions.

Copy code The code is as follows:

// Since this function returns another function, Among them, this function can access the free variable i
// All said, this internal function actually has permission to call the internal object.
function makeCounter() {
// i can only be accessed inside makeCounter
var i = 0;
return function () {
console.log( i);
} ;
}
// Note that counter and counter2 are different instances, each with i in its own range.
var counter = makeCounter();
counter(); // logs: 1
counter(); // logs: 2
var counter2 = makeCounter();
counter2() ; // logs: 1
counter2(); // logs: 2
alert(i); // Reference error: i is not defind (because i exists inside makeCounter).

In many cases, we don’t need multiple instances of makeCounter, and even in some cases, we don’t need to display the return value. OK, look down.

The core of the problem
When you declare a function like function foo(){} or var foo = function(){}, you can achieve self-execution by adding parentheses at the end, such as foo( ), look at the code:
Copy the code The code is as follows:

// Because I want the first one below A declared function can be executed by itself by adding a bracket () after it, such as foo(),
// because foo is just a reference to the expression function() { /* code */ }
var foo = function(){ /* code */ }
// ...Does it mean that even if you add parentheses at the end, it can be executed automatically?
function(){ /* code */ }(); // SyntaxError: Unexpected token (
//

The above code, if even run, the 2nd code will error , because when the parser parses the global function or function internal function keyword, it defaults to a function declaration instead of a function expression. If you do not explicitly tell the compiler, it will default to a function that lacks a name, and Throws a syntax error message because the function declaration requires a name.
Aside: function, parentheses, syntaxError (SyntaxError)
Interestingly, even if you add The previous name will also prompt a syntax error, but the reason is different from the above. If you add parentheses () after an expression, the expression will be executed immediately, but if you add parentheses () after a statement, it will be executed immediately. The meaning is completely different, his is just the grouping operator
Copy code The code is as follows: >// The following function is grammatically correct, but it is still just a statement // After adding parentheses (), an error will still be reported, because the grouping operator needs to contain the expression function foo(){ /* code */ }(); // SyntaxError: Unexpected token )
// But if you pass an expression in brackets (), no exception will be thrown
// But the foo function
function foo(){ /* code */ }( 1 );
// is still not executed because it is completely equivalent to the following code. After a function declaration, an unrelated one is declared. Expression:
function foo(){ /* code */ }
( 1 );


You can visit ECMA-262-3 in detail. Chapter 5. Functions for further information.
Self-executing function expression
To solve the above problem, it is very simple. We only need to use curly brackets to enclose all the code. Because statements cannot be included in brackets () in JavaScript, so at this point When parsing the function keyword, the parser will parse the corresponding code into a function expression instead of a function declaration.
Copy code The code is as follows:

// The following 2 brackets () will be executed immediately
(function () { /* code */ } ()); // It is recommended to use this
(function () { /* code */ })(); // But this can also be used
// Since brackets () and JS’s &&, XOR, comma and other operators disambiguate function expressions and function declarations
// so once the parser knows that one of them is already an expression, the other are all expressions by default
// However, please pay attention to the content explanation in the next chapter
var i = function () { return 10; } ();
true && function () { /* code */ } ();
0, function () { /* code */ } ();
// If you don’t care about the return value, or are not afraid of being difficult to read
// you can even You can add the unary operation symbol
!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
function () { /* code */ } ();
// There is another case, using the new keyword, it can also be used, but I am not sure about it Efficiency
// http://twitter.com/kuvos/status/18209252090847232
new function () { /* code */ }
new function () { /* code */ } () / / If you need to pass parameters, you only need to add parentheses ()

The parentheses mentioned above are for disambiguation. In fact, they are not necessary at all, because the parentheses are originally expected to be function expressions. But we still use it, mainly to make it easier for developers to read. When you assign these automatically executed expressions to a variable, we see brackets (() at the beginning, which can be understood quickly without the need to Scroll to the end to see if there are parentheses.
Use a closure to save the state.
Just like passing parameters when executing a normal function, self-executing function expressions can also pass parameters in this way, because closures can be referenced directly. With these parameters passed in, self-executing function expressions can effectively save state by using these locked incoming parameters.
Copy code The code is as follows:

// This code is wrong because the variable i never It’s not locked
// On the contrary, after the loop is executed, i only gets the value when we click
// Because at this time i really gets the value
// So no matter which connection is clicked , the final displayed ones are I am link #10 (if there are 10 a elements)
var elems = document.getElementsByTagName('a');
for (var i = 0; i < elems. length; i ) {
elems[i].addEventListener('click', function (e) {
e.preventDefault();
alert('I am link #' i);
}, 'false');
}
// This can be used because it is inside the self-executing function expression closure
// The value of i exists as the locked index and is executed in the loop After the end, although the value of i finally becomes the total number of elements in a (for example, 10)
// the lockedInIndex value inside the closure has not changed because it has been executed
// so when you click the connection time, the result is correct
var elems = document.getElementsByTagName('a');
for (var i = 0; i < elems.length; i ) {
(function (lockedInIndex) {
elems[i].addEventListener('click', function (e) {
e.preventDefault();
alert('I am link #' lockedInIndex);
}, 'false' );
})(i);
}
// You can also apply it as follows, using the self-executing function expression in the handler function
// instead of outside addEventListener
// But relatively speaking, the above code is more readable
var elems = document.getElementsByTagName('a');
for (var i = 0; i < elems.length; i ) {
elems[i].addEventListener('click', (function (lockedInIndex) {
return function (e) {
e.preventDefault();
alert('I am link #' lockedInIndex);
};
})(i), 'false');
}

In fact, the lockedInIndex variable in the above two examples can also be replaced by i. Because it does not act on the same function as the external i, there will be no problem. This is also the power of anonymous function closures.
The difference between a self-executing anonymous function and an immediately executed function expression
In this post, we have always called it a self-executing function, to be precise, it is a self-executing anonymous function (Self-executing anonymous function), but the original English text The author has always advocated the use of the name Immediately-Invoked Function Expression. The author also gave a bunch of examples to explain, okay, let's take a look:
Copy code The code is as follows:

// This is a self-executing function, the function executes itself internally, recursively
function foo() { foo(); }
// This is a self-executing anonymous function because there is no marked name
// You must use the arguments.callee attribute to execute itself
var foo = function () { arguments. callee(); };
// This may also be a self-executing anonymous function, just the foo tag name refers to itself
// If you change foo to something else, you will get a used-to -self-execute anonymous function
var foo = function () { foo(); };
// Some people call this a self-executing anonymous function (even if it is not), because it does not call itself, it Just execute it immediately.
(function () { /* code */ } ());
// Adding a label name to the function expression can facilitate debugging
// But it must be named, and the function will no longer It is anonymous
(function foo() { /* code */ } ());
// Immediately invoked function expression (IIFE) can also be self-executed, but it may not be commonly used
(function () { arguments.callee(); } ());
(function foo() { foo(); } ());
// In addition, the following code will execute on BlackBerry 5 Error, because in a named function expression, his name is undefined
// Haha, strange
(function foo() { foo(); } ());

I hope that some examples here can help everyone understand what self-execution is and what immediate calling is.
Note: arguments.callee is obsolete in ECMAScript 5 strict mode, so it cannot be used in this mode.

Final narration: Module mode
When talking about this immediately called function expression, I remembered the Module mode again. If you are not familiar with this mode, let’s take a look at the code first. :
Copy code The code is as follows:

// Create an anonymous function expression that is called immediately
// Return a variable, which contains what you want to expose
// The returned variable will be assigned to counter, not the function itself declared outside
var counter = (function () {
var i = 0;
return {
get: function () {
return i;
},
set: function (val) {
i = val ;
},
increment: function () {
return i;
}
};
} ());
// counter is a variable with multiple The object of the attribute. The above code actually reflects the attribute as the method
counter.get(); // 0
counter.set(3);
counter.increment(); // 4
counter.increment(); // 5
counter.i; // undefined because i is not a property of the returned object
i; // Reference error: i is not defined (because i only exists in closures)

For more introduction to the Module pattern, please visit my previous post: In-depth Understanding of JavaScript Series (2): Comprehensive Analysis of the Module Pattern.
More Reading
I hope that some of the above examples can give you an understanding of the expression of functions that are called immediately (that is, what we call self-executing functions). If you want to know more about the function and Module patterns For information, please continue to visit the websites listed below:
  1. ECMA-262-3 in detail. Chapter 5. Functions. - Dmitry A. Soshnikov
  2. Functions and function scope - Mozilla Developer Network
  3. Named function expressions - Juriy “kangax” Zaytsev
  4. Comprehensive analysis of Module mode- Ben Cherry (translated and edited by uncle)
  5. Closures explained with JavaScript - Nick Morgan
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Replace String Characters in JavaScript Replace String Characters in JavaScript Mar 11, 2025 am 12:07 AM

Detailed explanation of JavaScript string replacement method and FAQ This article will explore two ways to replace string characters in JavaScript: internal JavaScript code and internal HTML for web pages. Replace string inside JavaScript code The most direct way is to use the replace() method: str = str.replace("find","replace"); This method replaces only the first match. To replace all matches, use a regular expression and add the global flag g: str = str.replace(/fi

How do I create and publish my own JavaScript libraries? How do I create and publish my own JavaScript libraries? Mar 18, 2025 pm 03:12 PM

Article discusses creating, publishing, and maintaining JavaScript libraries, focusing on planning, development, testing, documentation, and promotion strategies.

How do I optimize JavaScript code for performance in the browser? How do I optimize JavaScript code for performance in the browser? Mar 18, 2025 pm 03:14 PM

The article discusses strategies for optimizing JavaScript performance in browsers, focusing on reducing execution time and minimizing impact on page load speed.

How do I debug JavaScript code effectively using browser developer tools? How do I debug JavaScript code effectively using browser developer tools? Mar 18, 2025 pm 03:16 PM

The article discusses effective JavaScript debugging using browser developer tools, focusing on setting breakpoints, using the console, and analyzing performance.

10 Ways to Instantly Increase Your jQuery Performance 10 Ways to Instantly Increase Your jQuery Performance Mar 11, 2025 am 12:15 AM

This article outlines ten simple steps to significantly boost your script's performance. These techniques are straightforward and applicable to all skill levels. Stay Updated: Utilize a package manager like NPM with a bundler such as Vite to ensure

How to Build a Simple jQuery Slider How to Build a Simple jQuery Slider Mar 11, 2025 am 12:19 AM

This article will guide you to create a simple picture carousel using the jQuery library. We will use the bxSlider library, which is built on jQuery and provides many configuration options to set up the carousel. Nowadays, picture carousel has become a must-have feature on the website - one picture is better than a thousand words! After deciding to use the picture carousel, the next question is how to create it. First, you need to collect high-quality, high-resolution pictures. Next, you need to create a picture carousel using HTML and some JavaScript code. There are many libraries on the web that can help you create carousels in different ways. We will use the open source bxSlider library. The bxSlider library supports responsive design, so the carousel built with this library can be adapted to any

Using Passport With Sequelize and MySQL Using Passport With Sequelize and MySQL Mar 11, 2025 am 11:04 AM

Sequelize is a promise-based Node.js ORM. It can be used with PostgreSQL, MySQL, MariaDB, SQLite, and MSSQL. In this tutorial, we will be implementing authentication for users of a web app. And we will use Passport, the popular authentication middlew

How do I use source maps to debug minified JavaScript code? How do I use source maps to debug minified JavaScript code? Mar 18, 2025 pm 03:17 PM

The article explains how to use source maps to debug minified JavaScript by mapping it back to the original code. It discusses enabling source maps, setting breakpoints, and using tools like Chrome DevTools and Webpack.

See all articles