javascript立即执行函数表达式(IIFE)

常用的两种写法:

(function(){ /* code */ }()); (推荐写法)

(function(){ /* code */ })();

Q:为什么这样写,函数就嗯那个立即执行?

A:因为在javascript里,括号内部不能包含语句,当解析器对代码进行解释的时候,先碰到了(),然后碰到function关键字就会自动将()里面的代码识别为函数表达式而不是函数声明。

eg:如下代码就会报错。

function(){ /* code */ }(); // SyntaxError: Unexpected token (

why?!因为在javascript代码解释时,当遇到function关键字时,会默认把它当做是一个函数声明,而不是函数表达式,如果没有把它显视地表达成函数表达式,就报错了,因为函数声明需要一个函数名,而上面的代码中函数没有函数名。(以上代码,也正是在执行到第一个左括号(时报错,因为(前理论上是应该有个函数名的。)

立即执行函数与闭包的暧昧关系:

像普通的函数传参一样,立即执行函数也能传参数。如果在函数内部再定义一个函数,而里面的那个函数能引用外部的变量和参数(闭包),利用这一点,我们能使用立即执行函数锁住变量保存状态。通过以下两段代码可更好理解:

<body>
  <div>0</div>
  <div>1</div>
  <div>2</div>
  <div>3</div>
</body>
<script>
  var nodes = document.getElementsByTagName("div");
  for (var i = 0; i < nodes.length; i++) {
    nodes[i].onclick = function () {
      console.log(i);
    }
  }
</script>
//一次点击div,输出的结果却不是0~3,输出的都是3。这是为什么呢?!

因为div节点的onclick事件是被异步触发的,当事件被触发的时候,for循化早已结束,此时变量 i 已经是3,所以div的onclick事件函数终顺着作用域从内到外查找变量变量i时,查到的值总是3。那样怎么办才能得到想要的呢?

<body>
  <div>0</div>
  <div>1</div>
  <div>2</div>
  <div>3</div>
</body>
<script>
  var nodes = document.getElementsByTagName("div");
  for (var i = 0; i < nodes.length; i++) {
    (function (i) {
      nodes[i].onclick = function () {
        console.log(i);
      }
    })(i)
  }
</script>
//此时控制台就会输出对应的值了,为什么呢?

因为在立即执行函数内部 i 的值被锁在内存中,尽管for循环结束后 i 的值已经改变,但是立即执行函数内部 i 的值并不会改变。

立即执行函数在模块化中的用处:

用立即执行函数处理模块化可以减少全局变量造成的空间污染,构造更多的私有变量。

// 创建一个立即执行的匿名函数
// 该函数返回一个对象,包含你要暴露的属性
// 如下代码如果不使用立即执行函数,就会多一个属性i
// 如果有了属性i,我们就能调用counter.i改变i的值
var counter = (function(){
  var i = 0;
  return {
    get: function(){
      return i;
    },
    set: function( val ){
      i = val;
    },
    increment: function() {
      return ++i;
    }
  };
})(); // counter其实是一个对象 counter.get(); // 0 counter.set( 3 ); counter.increment(); // 4 counter.increment(); // 5  counter.i; // undefined i并不是counter的属性 i; // ReferenceError: i is not defined (函数内部的是局部变量)

原文:Immediately-Invoked Function Expression (IIFE)

G~G~ Study。

时间: 2024-12-28 11:27:33

javascript立即执行函数表达式(IIFE)的相关文章

理解JavaScript的立即调用函数表达式(IIFE)

首先这是js的一种函数调用写法,叫立即执行函数表达式(IIFE,即immediately-invoked function expression).顾名思义IIFE可以让你的函数立即得到执行(废话). 一般来说,IIFE有以下几种用途: 1. 创建只使用一次的函数,并立即执行它. 2. 创建闭包,保存状态,隔离作用域. 3. 作为独立模块存在(例子如jQuery),防止命名冲突,命名空间注入(模块解耦). 1. 创建只使用一次的函数,并立即执行它 创建只使用一次的函数比较好理解,在需要调用函数的

IIFE(立即执行函数表达式)

我们经常会看到这样的写法: ;(fuction () { // do something })() 这就是一个简单的IIFE(立即执行函数表达式,immediately-invoked function expression)了. 这样的写法有什么好处呢?来简单分析一下. 1. 开头的分号 我们都知道,js是可以加分号或者不加分号的,在某些情况下,不加分号会让解析器解析出错,举个例子: var a = 0 , b = 0 ; a = b + 3 (b = a) // Uncaught TypeE

JS-立即执行函数表达式(IIFE)

javascript函数调用 在javascript中,每一个函数在被调用的时候都会创建一个执行上下文,在该函数内部定义的变量和函数只能在该函数内部被使用,而正是因为这个上下文,使得我们在调用函数的时候能创建一些私有变量. 先声明后调用 // 声明: var foo = function(){ /* code */ }; // 调用: foo(); 如果想不声明直接调用 function(){ /* code */ }(); // 报错:SyntaxError: Unexpected token

Javascript 自动执行函数(立即调用函数)

开头:各种原因总结一下javascript中的自动执行函数(立即调用函数)的一些方法,正文如下 在Javascript中,任何function在执行的时候都会创建一个执行上下文,因为function声明变量和function有可能只在该function内部,这个上下文,在调用function的时候,提供一些简单的方式来创建自由变量或私有子function. eg: // 由于该function里返回了另外一个function,其中这个function可以访问自由变量i // 所有说,这个内部的f

JavaScript中的函数表达式

在JavaScript中,函数是个非常重要的对象,函数通常有三种表现形式:函数声明,函数表达式和函数构造器创建的函数. 本文中主要看看函数表达式及其相关的知识点. 函数表达式 首先,看看函数表达式的表现形式,函数表达式(Function Expression, FE)有下面四个特点: 在代码中须出现在表达式的位置 有可选的函数名称 不会影响变量对象(VO) 在代码执行阶段创建 下面就通过一些例子来看看函数表达式的这四个特点. FE特点分析 例子一:在下面代码中,"add"是一个函数对象

javascript立即执行函数

javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花;当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解.  ( function(){…} )()  和  ( function (){…} () )  是两种javascript立即执行函数的常见写法; 最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达到函数定义后立即执行的目的; 后来发现加括号的原因并非如此.要理解立即执行函数,需要先理解一

javascript立即执行函数 (function(){})()

看到一段代码: (function(){ var outer = $('#subject'); outer.find('li').on('mouseover', mouseover); })() ( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,且这个函数必须是函数表达式,不能是函数声明. 这样写的作用: javascript中没用私有作用域的概念,如果在多人开发的项目上,你在全局或局部作用域中声明了一些变量,可能

深入理解javascript:揭秘命名函数表达式

这是一篇转自汤姆大叔的文章:http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html 前言 网上还没用发现有人对命名函数表达式进去重复深入的讨论,正因为如此,网上出现了各种各样的误解,本文将从原理和实践两个方面来探讨JavaScript关于命名函数表达式的优缺点. 简单的说,命名函数表达式只有一个用户,那就是在Debug或者Profiler分析的时候来描述函数的名称,也可以使用函数名实现递归,但很快你 就会发现其实是不切实际的.当然

立即执行函数表达式(自执行函数)

立即执行函数表达式 立即执行函数表达式,大部分人也称为自执行函数. 自执行函数的写法 匿名函数 (function(){ console.log(2) })() 具名函数 (function log(){ console.log(2) })() 自执行函数的传参 (function add(a, b){ console.log(a + b) })(1,2) 返回值 let fn = (function add(a,b){ return a + b; })(2,4); console.log(fn