JS基本功系列-立即执行函数

admin 2022年4月27日08:42:46评论33 views字数 4034阅读13分26秒阅读模式

前言

自动执行,执行完之后立即释放(就是说这个函数执行完之后自动销毁, 你再次调用的时候会报 ReferenceError的错误);
IIFE: immediately-invoked function expression

三种基本写法:

//第一种
(function ({

})(); // 看着清晰

// 第二种
(function ({

}()); // W3C建议,推荐

// 第三种
+function test({

}()


  // 1、简单示例
  // 用括号包裹匿名函数:因为括号包裹的是函数表达式,前后需要加分号
  (function ({
    var a = 1;
    var b = 2;
    console.log(a + b); // 3
  }());


// 2、参数问题
(function (a, b// 形参
  console.log(a + b); // 3
}(12)); // 实参


// 3、返回值:用变量接受表达式
var num = (function (a, b{
  return a + b;
}(12));

console.log(num); // 3

表达式执行

(1)括号包起来的一定是表达式

// ==>   (funiton test(){})

(2)一定是表达式才能被执行符号执行

// 被执行
(function test1({
  console.log(1); // 1
})();

// 被执行,有=号,它是一个表达式
var test2 = function ({
  console.log(1); // 1
}();

// 不传参报错,不是一个表达式,原因:JS引擎认为不传参数就是不是表达式
// 报语法错误:Uncaught SyntaxError: Unexpected token )
// function test3() {
//     console.log(1);
// }(); // 没传参

// 传入参数不报错,但不执行,原因:JS引擎认为传了参数就是表达式
function test5(a{

}

test5(6);  // 传参

(3)立刻执行函数:自动执行、执行完成以后立刻释放

// 括号包裹-会报错
(function test({
  var a = 1;
  var b = 2;
  console.log(a + b); // 3
}());
// 因为执行完毕即可销毁,外部调用不到test函数
console.log(test()); // Uncaught ReferenceError: test is not defined

// 表达式-不会报错
var test1 = function ({
  console.log(2); // 2
}();
console.log(test1); // undefined

(4)如果函数变为表达式,函数名就会被忽略

// 匿名函数
var num = (function ({
  return 123;
})();
console.log(num); // 123

// 忽略函数名
var num = (function test({
  return 123;
})();
console.log(num); // 123

(5)函数声明变为表达式的方法,在表达式前加 +、-、!、||、&&

// 1、函数声明:function test(){}
// 2、函数声明变为表达式(前面加符号):+function test(){}
// 3、表达式立刻执行(末尾加括号):+function test(){}()
+function test({
  console.log(1);//1
}();

1 && function test({
  console.log(1);//1
}();


//逗号也是一个运算符
var num1 = (12)
console.log(num1)//2,总是最后一个数字
var num2 = (123)
console.log(num2)//3

表达式小结

1.有括号;

2.有=号.

3.函数声明前面加 +、-、!、||、&&

立刻执行函数-经典面试题

//先上简单的:
function testf({
  var n = 10;
  var a = function ({
    console.log(n)
  }

  var b = function ({
    console.log(n);
  }
  return [a, b];
}

//testf执行完之后,testf的AO并没有销毁,
// (testf的AO里面还是包含n=10的)
//testf的AO还被a,b两个函数拽着
var arr = testf();
console.log(arr[0]());//10

上菜:

function test({
  var arr = [];

  for (var i = 0; i < 10; i++) {
    // 赋值语句,系统定义的时候为函数引用,访问不到里面的值
    // 只有在外部执行的时候才会看到里面的i值
    arr[i] = function (// 匿名函数
      document.write(i + ' ');
    }
  }

  // for循环 等价
  // var i = 0;
  // for(; i < 10; ) {
  //     arr[i] = function() {
  //         document.write(i + ' ');
  //     }
  //     i++;
  // }

  return arr;
}

var myArr = test();
console.log(myArr); // 10个匿名函数 [ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ]

for (var j = 0; j < 10; j++) {
  myArr[j](); // 10 10 10 10 10 10 10 10 10 10
}

// 答案:10个10
// 原因:
// 1、test中的for循环,在arr中存放了10个匿名函数,但是没执行
// 2、当for循环完毕之后,test函数中AO存放的i变量已经变为了10
// 3、当return arr的时候,形成了10个闭包,即10个匿名函数,虽然test的AO被销毁,但是返回的每个匿名函数中都有test的AO
// 4、当在外部for循环调用每个匿名函数的时候,输出的i都是10

如果想打印0-9,的解决方法:

// 第一种方法:需要立刻执行函数
function test({
  //var arr = [];

  for (var i = 0; i < 10; i++) {
    // 改为立刻执行函数
    (function ({
      document.write(i + ' ');
    }());
  }

  //return arr;
}

test();


// 第二种方法:外部传入
function test({
  var arr = [];

  for (var i = 0; i < 10; i++) {
    arr[i] = function (num{
      document.write(num + ' ');
    }
  }

  return arr;
}

var myArr = test();
console.log(myArr); // [ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ]

for (var j = 0; j < 10; j++) {
  myArr[j](j); // 0 1 2 3 4 5 6 7 8 9
}


// 第三种方法:立刻执行保存值(最常用)==>非常经典的方法
function test({
  var arr = [];

  for (var i = 0; i < 10; i++) {
    // 实际循环立刻执行函数:立刻执行函数保存i值
    (function (j{//注意:这里的j是立即执行函数的形参!!!
      // 立即执行函数AO中的 j = 0, 1, 2, 3......
      // 每个立刻执行函数中都有一个唯一的j值
      arr[j] = function ({
        // 访问的是立刻执行函数AO中的j值:0, 1, 2....
        document.write(j + ' ');
      }
    })(i);
  }

  return arr;
}

// 上面的for循环可以这么理解:
for (var p = 0; p < 10; p++) {
  (function (j{
    //具体逻辑
    //...
  })(p)
}

var myArr = test();
console.log(myArr); // [ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ]

for (var j = 0; j < 10; j++) {
  myArr[j](); //0 1 2 3 4 5 6 7 8 9
}




经典题2:


var a = 10;
if (function b({}) {//分析:一个函数如果被括号括起来,那么就是一个表达式
                      //被当做表达式的时候,其函数名就可以被忽略
                      //b只要被忽略,放到typeof中就是undefined
  a += typeof (b);
}
console.log(a);//10 undefined


原文始发于微信公众号(Th0r安全):JS基本功系列-立即执行函数

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月27日08:42:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JS基本功系列-立即执行函数http://cn-sec.com/archives/949789.html

发表评论

匿名网友 填写信息