fbpx
维基百科

立即调用函数表达式

立即调用函数表达式(英文:immediately-invoked function expression,缩写:IIFE[1],是一种利用JavaScript函数生成新作用域的编程方法。

立即调用函数表达式可以令其函数中声明的变量绕过JavaScript的变量置顶声明规则,还可以避免新的变量被解释成全域变量或函数名占用全域变量名的情况。与此同时它能在禁止访问函数内声明变量的情况下允许外部对函数的调用。有时,这种编程方法也被叫做“自执行(匿名)函数”,但“立即调用函数表达式”是语义上最准确的术语。 [2][1][3][4]

用法 编辑

立即调用函数表达式拥有数种不同的写法[5]。最常见的一种是将函数表达式字面量置于圆括号(分组运算符)之内,然后使用圆括号调用函数。[6][7]

(function() {  // 这里的语句将获得新的作用域 })(); 

若要将作用域外变量传递进函数,则按下述方式书写:

(function(a, b) {  // a == 'hello'  // b == 'world' })('hello', 'world'); 

开头的括号可能会因为解释器的分号自动插入特性造成一些问题。括号本用于明确字面量为表达式以与函数声明语句区分,但解释器可能将括号解释为对以上一行中结尾的变量名为名的函数的调用。在一些省略分号的程序中,可见将分号至于行首的做法。这样的分号被称为“防御性分号”[8][9],举例:

a = b + c ;(function() { // 故意将分号放在这里  // 代码 })(); 

如此书写,以防止语句被理解为对函数c的调用(c(...))。

例子 编辑

理解立即调用函数表达式的关键在于认清JavaScript拥有函数作用域,但没有块作用域(ES6之前),且通过指针(而非复制)将变量传入一个函数闭包[10] ES6 引入了新关键字 let和 const,用它们定义的常量和变量具有块级作用域。

求值上下文(Evaluation context) 编辑

缺少块作用域意味着一个在类似于for循环的块中声明的变量会被置顶到其所包含的函数中。如果一个内部函数依赖于一个外部变量,而该外部变量被外部函数更改,那么执行内函数就有些困难。举例,我们在声明函数之后,但在定义函数之前,改变一个变量的值。[11]

var v, getValue; v = 1; getValue = function() { return v; }; v = 2;   getValue(); // 2 

当我们手动给v赋值时这结果似乎没什么问题。不过,如果getValue()是在一个循环中被定义的,那么就可能出现预想外的结果。

var v, getValue; v = 1; getValue = (function(x) {  return function() { return x; }; })(v); v = 2; getValue(); // 1 

此例中,function将 v 作为参数传入并立即调用,保护了内部函数的执行上下文。[12]

David Herman's作品 Effective JavaScript 包含了一个用来在循环中求值导致问题的例子。[13] 虽然他的例子刻意编写得非常复杂,但是原因都是缺乏块作用域导致的.[14]

利用IIFE建立真正的私有函数和变量,并用闭包访问 编辑

立即调用函数表达式也可以用来创建私有方法来访问函数,不仅起到保护作用,同时也暴露了一些可以后续使用的属性。[15] 下面的例子来自于 Alman's 关于IIFE的网帖。[1]

// 'counter' 函数返回一个具有属性的对象, 这里的属性就是 // get set等函数 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 这个数据由IIFE封装,它并不是 counter的属性。同样的,如果我们试图访问 i 也会收到错误,因为 i 并没有在全局作用域中定义。

术语 编辑

"立即调用函数表达式" 最早称为“自执行(匿名)函数”[1][5] 但是立即执行的函数不一定是匿名的。 ECMAScript 5的 strict mode 禁止arguments.callee,[16] 因此,这个术语不够准确.[3][12]

在lambda-calculus(λ演算)中,这个构造称为 "redex", 用来化简表达式, 参阅:Reduction strategy (code optimization).

参考 编辑

  1. ^ 1.0 1.1 1.2 1.3 Alman, Ben. . 2010 [4 February 2013]. (原始内容存档于2013-01-20). 
  2. ^ Resig, John. Pro JavaScript Techniques. Apress. 2006: 29. ISBN 9781430202837. 
  3. ^ 3.0 3.1 Osmani, Addy. Learning JavaScript Design Patterns. O'Reilly. 2012: 206. ISBN 9781449334871. 
  4. ^ Baagoe, Johannes. Closing parenthesis in function's definition followed by its call. [19 April 2010]. (原始内容存档于2011-01-22). 
  5. ^ 5.0 5.1 Lindley, Cody. JavaScript Enlightenment. O'Reilly. 2013: 61. ISBN 9781449342883. 
  6. ^ Zakas, Nicholas. Maintainable JavaScript. O'Reilly. 2012: 44. ISBN 9781449327682. 
  7. ^ Crockford, Douglas. . [3 February 2013]. (原始内容存档于2012-03-05). 
  8. ^ "JavaScript Semicolon Insertion: Everything you need to know (页面存档备份,存于互联网档案馆)", Friday, May 28, 2010
  9. ^ "Semicolons in JavaScript are optional (页面存档备份,存于互联网档案馆)", by Mislav Marohnić, 07 May 2010
  10. ^ Haverbeke, Marijn. Eloquent JavaScript. No Starch Press. 2011: 29–30. ISBN 9781593272821. 
  11. ^ Alman, Ben. . Github. [5 February 2013]. (原始内容存档于2021-04-14). 
  12. ^ 12.0 12.1 Otero, Cesar; Larsen, Rob. Professional jQuery. John Wiley & Sons. 2012: 31. ISBN 9781118222119. 
  13. ^ Herman, David. Effective Javascript. Addison-Wesley. 2012: 44–45. ISBN 9780321812186. 
  14. ^ Zakas, Nicholas C. Mimicking Block Scope. Professional JavaScript for Web Developers. John Wiley & Sons. 2011. ISBN 9781118233092. 
  15. ^ Rettig, Pascal. Professional HTML5 Mobile Game Development. John Wiley & Sons. 2012: 145. ISBN 9781118301333. 
  16. ^ . Mozilla JavaScript Reference. Mozilla Developer Network. [4 February 2013]. (原始内容存档于2013-05-25). 

外部链接 编辑

  • . Mozilla JavaScript Reference. Mozilla Developer Network. [4 February 2013]. (原始内容存档于2013-05-25). 
  • Soshnikov, Dmitry. . [4 February 2013]. (原始内容存档于2021-02-28). 

立即调用函数表达式, 英文, immediately, invoked, function, expression, 缩写, iife, 是一种利用javascript函数生成新作用域的编程方法, 可以令其函数中声明的变量绕过javascript的变量置顶声明规则, 还可以避免新的变量被解释成全域变量或函数名占用全域变量名的情况, 与此同时它能在禁止访问函数内声明变量的情况下允许外部对函数的调用, 有时, 这种编程方法也被叫做, 自执行, 匿名, 函数, 是语义上最准确的术语, 目录, 用法, 例子, 求值上下文,. 立即调用函数表达式 英文 immediately invoked function expression 缩写 IIFE 1 是一种利用JavaScript函数生成新作用域的编程方法 立即调用函数表达式可以令其函数中声明的变量绕过JavaScript的变量置顶声明规则 还可以避免新的变量被解释成全域变量或函数名占用全域变量名的情况 与此同时它能在禁止访问函数内声明变量的情况下允许外部对函数的调用 有时 这种编程方法也被叫做 自执行 匿名 函数 但 立即调用函数表达式 是语义上最准确的术语 2 1 3 4 目录 1 用法 2 例子 2 1 求值上下文 Evaluation context 2 2 利用IIFE建立真正的私有函数和变量 并用闭包访问 3 术语 4 参考 5 外部链接用法 编辑立即调用函数表达式拥有数种不同的写法 5 最常见的一种是将函数表达式字面量置于圆括号 分组运算符 之内 然后使用圆括号调用函数 6 7 function 这里的语句将获得新的作用域 若要将作用域外变量传递进函数 则按下述方式书写 function a b a hello b world hello world 开头的括号可能会因为解释器的分号自动插入特性造成一些问题 括号本用于明确字面量为表达式以与函数声明语句区分 但解释器可能将括号解释为对以上一行中结尾的变量名为名的函数的调用 在一些省略分号的程序中 可见将分号至于行首的做法 这样的分号被称为 防御性分号 8 9 举例 a b c function 故意将分号放在这里 代码 如此书写 以防止语句被理解为对函数c的调用 c 例子 编辑理解立即调用函数表达式的关键在于认清JavaScript拥有函数作用域 但没有块作用域 ES6之前 且通过指针 而非复制 将变量传入一个函数闭包 10 ES6 引入了新关键字 let和 const 用它们定义的常量和变量具有块级作用域 求值上下文 Evaluation context 编辑 缺少块作用域意味着一个在类似于for循环的块中声明的变量会被置顶到其所包含的函数中 如果一个内部函数依赖于一个外部变量 而该外部变量被外部函数更改 那么执行内函数就有些困难 举例 我们在声明函数之后 但在定义函数之前 改变一个变量的值 11 var v getValue v 1 getValue function return v v 2 getValue 2 当我们手动给v赋值时这结果似乎没什么问题 不过 如果getValue 是在一个循环中被定义的 那么就可能出现预想外的结果 var v getValue v 1 getValue function x return function return x v v 2 getValue 1 此例中 function将 v 作为参数传入并立即调用 保护了内部函数的执行上下文 12 David Herman s作品 Effective JavaScript 包含了一个用来在循环中求值导致问题的例子 13 虽然他的例子刻意编写得非常复杂 但是原因都是缺乏块作用域导致的 14 利用IIFE建立真正的私有函数和变量 并用闭包访问 编辑 立即调用函数表达式也可以用来创建私有方法来访问函数 不仅起到保护作用 同时也暴露了一些可以后续使用的属性 15 下面的例子来自于 Alman s 关于IIFE的网帖 1 counter 函数返回一个具有属性的对象 这里的属性就是 get set等函数 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 这个数据由IIFE封装 它并不是 counter的属性 同样的 如果我们试图访问 i 也会收到错误 因为 i 并没有在全局作用域中定义 术语 编辑 立即调用函数表达式 最早称为 自执行 匿名 函数 1 5 但是立即执行的函数不一定是匿名的 ECMAScript 5的 strict mode 禁止arguments callee 16 因此 这个术语不够准确 3 12 在lambda calculus l演算 中 这个构造称为 redex 用来化简表达式 参阅 Reduction strategy code optimization 参考 编辑 1 0 1 1 1 2 1 3 Alman Ben Immediately Invoked Function Expressions 2010 4 February 2013 原始内容存档于2013 01 20 Resig John Pro JavaScript Techniques Apress 2006 29 ISBN 9781430202837 3 0 3 1 Osmani Addy Learning JavaScript Design Patterns O Reilly 2012 206 ISBN 9781449334871 Baagoe Johannes Closing parenthesis in function s definition followed by its call 19 April 2010 原始内容存档于2011 01 22 5 0 5 1 Lindley Cody JavaScript Enlightenment O Reilly 2013 61 ISBN 9781449342883 Zakas Nicholas Maintainable JavaScript O Reilly 2012 44 ISBN 9781449327682 Crockford Douglas Code Conventions for the JavaScript Programming Language 3 February 2013 原始内容存档于2012 03 05 JavaScript Semicolon Insertion Everything you need to know 页面存档备份 存于互联网档案馆 Friday May 28 2010 Semicolons in JavaScript are optional 页面存档备份 存于互联网档案馆 by Mislav Marohnic 07 May 2010 Haverbeke Marijn Eloquent JavaScript No Starch Press 2011 29 30 ISBN 9781593272821 Alman Ben simple iife example js Github 5 February 2013 原始内容存档于2021 04 14 12 0 12 1 Otero Cesar Larsen Rob Professional jQuery John Wiley amp Sons 2012 31 ISBN 9781118222119 Herman David Effective Javascript Addison Wesley 2012 44 45 ISBN 9780321812186 Zakas Nicholas C Mimicking Block Scope Professional JavaScript for Web Developers John Wiley amp Sons 2011 ISBN 9781118233092 Rettig Pascal Professional HTML5 Mobile Game Development John Wiley amp Sons 2012 145 ISBN 9781118301333 Strict mode Mozilla JavaScript Reference Mozilla Developer Network 4 February 2013 原始内容存档于2013 05 25 外部链接 编辑Functions and function scope Mozilla JavaScript Reference Mozilla Developer Network 4 February 2013 原始内容存档于2013 05 25 Soshnikov Dmitry ECMA 262 3 in detail Chapter 5 Functions 4 February 2013 原始内容存档于2021 02 28 取自 https zh wikipedia org w index php title 立即调用函数表达式 amp oldid 74459047, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。