Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[js] 第79天 举例说明什么是IIFEs?它有什么好处? #570

Open
haizhilin2013 opened this issue Jul 3, 2019 · 9 comments
Open
Labels
js JavaScript

Comments

@haizhilin2013
Copy link
Collaborator

第79天 举例说明什么是IIFEs?它有什么好处?

@haizhilin2013 haizhilin2013 added the js JavaScript label Jul 3, 2019
@ghost
Copy link

ghost commented Jul 4, 2019

Instantly Invoked Function Expression 即时调用函数表达式

示例

;(function () {
    // ... statements
    return ...
)()
  • 最好在 IIFE 前追加分号 ; 来避免解析时与前一个表达式合并出现问题

好处

  • 创建一个局部作用域隔离变量;但在 ES6 拥有了块级作用域后变得没有必要,可以用语句块 { ... } 配合 let/const 替代
  • 将运行逻辑转化为可求值的表达式,弥补 JavaScript 基本逻辑语句不是表达式的缺陷
    • e.g.
      const a = (() => {
          if (...) return 1
          else return 0
      })()
      基本等价于
      let a
      if (...) a = 1
      else a = 0

@thisisandy
Copy link

在v8引擎架构里,对于top-level 的代码会做 pre-parsing 来检测是否有语法错误。然而这是一种性能浪费,应为在full-parsing 的时候遇到语法错误自然会抛错。 所以V8 提供了一种hack方式就是IIFE,绕过对top-level代码的 pre-parsing

@sangjunke
Copy link

可以使用+ - = !符号将匿名函数或函数声明转为函数表达式
eg:

! function () {
            console.log(window)
        }(window);

@nowherebutup
Copy link

1.创建局部作用域,避免全局污染

@forever-z-133
Copy link

自执行匿名函数,我一般用它来 1. 独立作用域,2. 直接递归,3. 节约变量

// 我经常这样子来写异步递归,不用单写函数和变量然后调用
(function loop(min, max) {
  if (++min > max) return;
  // ......
  loop(min, max);
}(1, 10);
// 还有更多节约变量的方式
var getInfo = (function() {
  var info = null;
  return function(callback) {
    if (info) callback();
    ajax(api, function(res){
      info = res.data; callback();
    });
  }
})();

@zhoushaw
Copy link

zhoushaw commented Jul 4, 2019

含义

IIFE: 立即执行函数

写法:

(function(){
     var name = 'shaw';
})()

好处

1.在let、const块级作用域未出来时,我们常常会写出这样的代码

for (var i=0;i<10;i++) {
     (function(i){
          setTimeout(function(){
               console.log(i);
          }, 100*i);
     })(i)
}

通过立即执行函数来创造一个新的作用域并缓存变量,来解决闭包带来的副作用问题

2.模块化

由于立即执行函数,不污染外部作用域的原则,因此诞生了umd模块的写法。一般主流的框架都会提供umd格式的js,通过script标签注入页面后会生成唯一一个全局变量,内部变量都不会暴露出来

@seho-dev
Copy link

立即执行函数为什么可以立即执行?

  1. 必须是函数表达式
  2. 写完后要立即调用()

而(),! ?;等符号就会把函数声明语句转换成函数表达式

@smile-2008
Copy link

Instantly Invoked Function Expression 即时调用函数表达式

示例

;(function () {
    // ... statements
    return ...
)()
  • 最好在 IIFE 前追加分号 ; 来避免解析时与前一个表达式合并出现问题

好处

  • 创建一个局部作用域隔离变量;但在 ES6 拥有了块级作用域后变得没有必要,可以用语句块 { ... } 配合 let/const 替代

  • 将运行逻辑转化为可求值的表达式,弥补 JavaScript 基本逻辑语句不是表达式的缺陷

    • e.g.

      const a = (() => {
          if (...) return 1
          else return 0
      })()

      基本等价于

      let a
      if (...) a = 1
      else a = 0

@xiaoqiangz
Copy link

IIFES: 自执行函数, 创建局部作用域,避免全局污染。
var obj = (function(){
return {}
}())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js JavaScript
Projects
None yet
Development

No branches or pull requests

9 participants