ZiMingの宝藏之地
首页项目归档笔记照片墙音乐灵境说说杂谈友链关于
知识库
138 篇文档 / 65 个目录
目录菜单
主页知识库
飞书飞书知识库/前端/面试/JS/js 进阶/闭包 & 立即执行函数

闭包 & 立即执行函数

同步时间:2026-05-28T14:46:01

https://blog.csdn.net/m0_66706006/article/details/132124323

立即执行函数,闭包函数_立即执行函数闭包

//立即执行函数的两种写法

//第一种:用括号把整个函数定义和调用包裹起来
(function(){
 //function body
}())

//第二种:用括号把函数定义包裹起来,后面再加括号
(function (){
 //function body
})()

//立即执行函数的参数
// 如果立即执行函数中需要全局变量,全局变量会被作为一个参数传递给立即执行函数
  //(下例中的i就是一个全局变量,i代表的是实参,j是i在立即执行函数中的形参)。
(function(j){
//代码中可以使用j
})(i)

闭包的概念

闭包就是能够读取其他函数内部变量的函数。 由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。 所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

闭包的用途

闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

当想访问函数内部的变量时,或想把函数内部的变量抛到外面,就需要用到闭包的写法。

父函数将子函数作为返回值,再将子函数赋值给一个变量。所以子函数会存在于内存中,而子函数依赖于父函数的存在,所以父函数也会存在于内存中。也就不会被垃圾回收机制回收。

闭包的写法(用法)

在主函数function内部,定义闭包function函数。但是执行调用还是在外面的,即通过return才能调用执行

function funOne()
  var num=0

    function funTwo(){
        num++
        return num
    }

  return funTwo
}
var fun=funOne()

6. 闭包与匿名函数结合(用法)

var funOne=(function(){
   var num=0

  return function(){
      num++
      return num
  }
})()

闭包和立即执行函数的区别

闭包(Closure)和立即执行函数(Immediately Invoked Function Expression,IIFE)是 JavaScript 中两个不同的概念,但它们之间存在联系。下面是它们的区别和联系:

闭包

  1. 定义:闭包是指一个函数能够记住并访问其创建时的词法作用域,即使该函数在其原始作用域之外被调用。

  2. 用途:闭包主要用于数据封装、创建私有变量、实现模块模式、柯里化函数等。

  3. 行为:闭包允许函数访问和操作外部作用域中的变量,即使外部函数已经执行完毕。

  4. 示例:

function createClosure() {
  let secret = "I'm a secret!";
  return function() {
    console.log(secret);
  };
}
const myClosure = createClosure();
myClosure(); // 访问外部作用域的变量

立即执行函数

  1. 定义:IIFE 是一种在定义后立即执行的函数表达式。

  2. 用途:IIFE 主要用于创建局部作用域、避免全局变量污染、执行自执行代码块等。

  3. 行为:IIFE 执行后会立即完成其功能,通常不保留状态或在执行后继续存在。

  4. 示例:

(function() {
  console.log('This will be executed immediately.');
})();

联系

  • 局部作用域:IIFE 和闭包都可以创建局部作用域,避免变量污染。

  • 匿名函数:IIFE 通常是一个匿名函数表达式,而闭包可以是匿名或具名函数。

  • 执行时机:IIFE 在定义后立即执行,而闭包可以在定义后随时调用,不一定立即执行。

区别

  • 状态保持:闭包可以保持状态,因为它可以访问外部作用域的变量;IIFE 执行完毕后通常不会保留状态。

  • 重复使用:闭包可以被多次调用,每次调用都可以访问其创建时的作用域;IIFE 执行一次后,其作用域和状态就不存在了。

  • 目的:闭包主要用于利用作用域链的特性,而 IIFE 主要用于立即执行代码块,避免污染全局作用域。

总结来说,闭包是一种特性,它允许函数访问创建时的作用域;而 IIFE 是一种模式,它是一种立即执行的函数表达式,通常用于创建局部作用域。两者在 JavaScript 编程中都非常有用,但它们的应用场景和目的不同。

闭包和立即执行函数 带参

当然,我可以给出闭包和立即执行函数(IIFE)带参数的例子。

闭包带参数的例子:

闭包通常用于封装私有变量和函数,下面是一个带参数的闭包的例子,其中参数用于配置闭包的行为:

function createClosure(msg) {
  let secretMessage = msg; // 闭包可以访问这个变量

  return function() {
    console.log(secretMessage);
  };
}

// 创建一个闭包实例,传入参数 "Hello, Closure!"
const myClosure = createClosure("Hello, Closure!");

// 调用闭包函数,输出传递给 createClosure 的参数
myClosure(); // 输出: Hello, Closure!

在这个例子中,createClosure 函数接收一个参数 msg,并在内部创建了一个闭包函数。这个闭包函数可以访问 createClosure 函数的局部变量 secretMessage。

立即执行函数带参数的例子:

IIFE 可以接收参数,并且立即执行这些参数:

(function(msg) {
  console.log('IIFE with parameter:', msg);
})('Hello, IIFE!');

// 带多个参数的 IIFE
(function(name, age) {
  console.log('Name:', name, 'Age:', age);
})('Alice', 30);

在这个例子中,第一个 IIFE 接收一个参数 msg 并立即执行,打印出这个参数。第二个 IIFE 接收两个参数 name 和 age,同样立即执行并打印这些参数。

IIFE 带参数的用法非常适合于配置函数或工厂函数的场景,其中参数用于定制函数的行为或返回值。

闭包

闭包(Closure)是 JavaScript 中一个非常重要的特性,它指的是一个函数能够记住并访问其创建时的词法作用域,即使这个函数在其原始作用域之外被执行。简单来说,闭包允许函数访问创建时的作用域中的变量,即便函数在其原始作用域之外被调用。

以下是闭包的一些关键点:

  1. 词法作用域:在 JavaScript 中,函数可以访问它们在定义时所在的作用域中的变量,而不仅仅是调用时所在的作用域。

  2. 数据封装:闭包可以用来封装数据,使得外部代码不能直接访问这些数据,而是通过函数间接访问。

  3. 记忆功能:闭包可以“记住”每次调用时的状态,因为它们可以访问外部函数的变量。

  4. 延迟计算:闭包可以用来实现延迟计算或异步操作。

  5. 高阶函数:函数可以作为另一个函数的参数或返回值,这是闭包的一个重要应用。

下面是一个简单的闭包示例:

function createClosure() {
  let secret = "I'm a secret!";
  return function() {
    console.log(secret);
  };
}

const myClosure = createClosure();
myClosure(); // 输出: I'm a secret!

在这个例子中,createClosure 函数创建了一个闭包,这个闭包可以访问 createClosure 函数内的变量 secret。即使 createClosure 函数执行完毕后,闭包仍然可以访问 secret。

闭包在 JavaScript 中有着广泛的应用,包括但不限于模块模式、事件处理器、异步编程等。理解闭包对于编写高效、可维护的 JavaScript 代码非常重要。

使用案例

闭包的使用案例非常广泛,以下是一些常见的例子:

  1. 数据私有化: 通过闭包,可以在函数内部创建私有变量,这些变量不能被外部直接访问,只能通过内部函数间接访问。
function createCounter() {
  let count = 0;
  return {
    increment: function() { count++; },
    decrement: function() { count--; },
    value: function() { return count; }
  };
}

const counter = createCounter();
console.log(counter.value()); // 0
counter.increment();
console.log(counter.value()); // 1
  1. 模块模式: 使用闭包实现模块模式,可以封装变量和功能,防止全局命名冲突。
const myModule = (function() {
  let privateVar = 'I am private';

  return {
    publicMethod: function() {
      console.log(privateVar);
    }
  };
})();

myModule.publicMethod(); // 'I am private'
// privateVar is not accessible here
  1. 函数工厂: 创建返回函数的函数,这些返回的函数可以记住创建时的状态。
function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

const add5 = makeAdder(5);
console.log(add5(3)); // 8
  1. 柯里化(Currying): 将一个多参数的函数转换成多个单参数的函数,每个单参数函数返回下一个参数的函数。
function curriedAdd(a) {
  return function(b) {
    return a + b;
  };
}

const add10 = curriedAdd(10);
console.log(add10(5)); // 15
  1. 事件处理器: 使用闭包可以持久化事件处理器的状态,即使在多次事件触发之间。
document.addEventListener('click', function() {
  console.log('Button was clicked!');
});

// 每次点击都会打印消息,闭包保持了事件监听器的状态
  1. 异步编程: 闭包在异步编程中非常有用,可以保持异步函数的状态。
async function fetchData(url) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('Data from ' + url);
    }, 1000);
  });
}

fetchData('https://api.example.com/data')
  .then(data => console.log(data)); // 保持了异步操作的状态
  1. 节流(Throttling)和防抖(Debouncing): 闭包可以用来实现节流和防抖函数,控制函数执行的频率。
// 节流示例
function throttle(func, limit) {
  let inThrottle;
  return function() {
    const args = arguments;
    const context = this;
    if (!inThrottle) {
      func.apply(context, args);
      inThrottle = true;
      setTimeout(() => (inThrottle = false), limit);
    }
  };
}

闭包是 JavaScript 中非常强大的特性,它提供了一种方式来创建具有持久状态的函数,这在很多编程场景中都非常有用。

立即执行匿名函数 和 闭包的使用

立即执行匿名函数(Immediately Invoked Function Expression,简称 IIFE)是一种在定义后立即执行的匿名函数表达式。这种模式在 JavaScript 中非常常见,主要用于创建局部作用域,避免污染全局命名空间,以及执行自执行代码块。

IIFE 有几种不同的形式,以下是一些常见的示例:

基本形式

(function() {
  console.log('This will be executed immediately.');
})();

这个函数被定义后立即执行,输出 "This will be executed immediately."。

带参数的形式

(function(param) {
  console.log('Immediate execution with parameter:', param);
})('Hello World');

这个 IIFE 接受一个参数,并在执行时传递了 'Hello World'。

使用闭包

(function() {
  let secret = 'I am a secret!';
  this.revealSecret = function() {
    console.log(secret);
  };
})();
revealSecret(); // 输出: I am a secret!

这个 IIFE 创建了一个闭包,并且向全局对象添加了一个 revealSecret 函数,用于访问 IIFE 的内部变量 secret。

使用在模块模式

const myModule = (function() {
  let privateVar = 'I am private';

  return {
    publicMethod: function() {
      console.log(privateVar);
    }
  };
})();

myModule.publicMethod(); // 输出: I am private

这个 IIFE 用于实现模块模式,其中 privateVar 是私有变量,只能通过返回对象的 publicMethod 访问。

使用在异步执行

;(async function() {
  console.log('This will be executed immediately with async/await.');
  await new Promise(resolve => setTimeout(resolve, 1000));
  console.log('This will be executed after 1 second.');
})();

这个 IIFE 使用了 async/await 语法,即使使用了 await,它仍然会立即执行。

避免在行首使用

(function() {
  // Some code here...
})();

在 JavaScript 中,如果 IIFE 直接写在行首,某些压缩工具可能会将其与代码块混淆。为了避免这种情况,可以在 IIFE 前加上一个分号 ;。

IIFE 是 JavaScript 中一个非常有用的模式,它提供了一种创建自包含代码块的方法,有助于保持代码的封装性和组织性。

Table of Contents