• JavaScript的函数IIFE


    javaScritp的函数(IIFE)

    一、认识函数

      javaScritp中的的函数

    // 函数声明语法定义
    function fun1(name, age) {
        console.log(name + ',' + age);
    }
    fun1('Amy', 18); //Amy,18
    // 函数表达式定义
    var fun2 = function(name, age) {
        console.log(name + ',' + age);
    }
    fun1('Amy', 18); //Amy,18

      

      javaScript函数带默认参数

    /* 默认参数 */
    function fun1(name, age = 17) {
        console.log(name + ',' + age);
    }
    
    fun1('Amy', 18); //Amy,18
    fun1('Amy', ''); // Amy,
    fun1('Amy'); // Amy,17
    fun1("Amy", null); // Amy,null

      

      函数参数默认值存在暂时性死区,在函数参数默认值表达式中,还未初始化赋值的参数值无法作为其他参数的默认值。

    function fun2(x, y = x) {
        console.log(x, y);
    }
    fun2(1); // 1 1
    
    function fun3(x = y) {
        console.log(x);
    }
    fun3();  // ReferenceError: y is not defined

      

      javaScript函数 不定参数

    // 不定参数用来表示不确定参数个数
    function fun4(...values) {
        console.log(values.length);
    }
    fun4(1, 2); //2
    fun4(1, 2, 3, 4); //4

      

      Function的构造定义

    通过Function构造函数创建函数,可向构造函数中传入任意数量的参数,但值得注意的是传入的最后一个参数会作为函数体,而其他参数则作为参数传入函数中。用该方法去定义函数是不推荐使用的,因为该语法会导致解析两次代码,第一次解析常规ECMAScript代码,第二次解析传入构造函数的字符串,影响性能。

    var functionName = new Function("value",...,"函数体");
    var f2=new Function("n1","n2","return n1+n2;");
    console.log(f2(1,2)); // 3

    注:函数是引入值类型,所以函数名仅仅是指向函数的指针,当使用函数名去赋值给另一个变量名时,仅仅复制的是一个指针。即在下列a设置为null时,仅将a存的指针消除而已,不会影响b调用函数。

    var a = b = function(value1){
        return value1;
    }
    a = null;
    b(1);

    function中的默认对象叫arguments,类似数组,但不是数组,该对象是传递给函数的参数。我们可以通过这个arguments知道该函数有多少个参数

    function counter(){
        var sum=0;
        for(var i=0;i<arguments.length;i++){
                sum+=arguments[i];
        }
         return sum;
    }
    console.log(counter(199,991,1,2,3,4,5)); // 1205
    console.log(counter()); // 0

    注:这里的arguments是一个隐式对象,不声明也在函数中,内部函数可以访问外部函数的任意内容,但是不能直接访问外部函数的arguments与this对象。

    function f1() {
        console.log(arguments.length);
        f2=function() {
            console.log(arguments.length);
        }
         return f2;
    }
    
    var f=f1(1,2,3); // 3
    f(); // 0

      

      function.call -调用一个对象的一个方法,以另一个对象替换当前对象

    /*构造函数*/
    function Student(name,age){
           this.name=name;
           this.age=age;
    }
               
    show=function(add){
           console.log(add+":"+this.name+","+this.age);
    }
               
    //通过new关键字调用构造函数,创建一个对象tom
    var rose=new Student("rose",18);
    var jack=new Student("jack",20);
              
    //调用show方法,指定上下文,指定调用对象,this指向rose,“大家好是参数”
    show.call(rose,"大家好"); // 大家好:rose,18
    show.call(jack,"Hello"); // Hello:jack,20

    call方法中的参数都可以省去,第1个参数表示在哪个对象上调用该方法,或this指向谁,如果不指定则会指向window对象

    var name="无名";
    var age=18; // 全局变量
    show.call(); // undefined:无名,18

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

    块级作用域与函数作用域

     function calc(){
          for(var i=0;i<5;i++){
                console.log(i); //  //0,1,2,3,4
          }
          console.log(i); // 5
    }
    calc();

    函数没有块级作用域所以后面输出的i是5,没有报错

    解决方法,模拟一个块级作用域

     function calc() {
           //IIFE
           (function() {
                   for(var i = 0; i < 5; i++) {
                         console.log(i); //0,1,2,3,4
                   }
            })();       
          console.log(i); //报错
    }
    
    calc();

      函数表达式或匿名对象立即执行

    //调用匿名函数
    (function() {
         console.log("这是一个函数表达式");
     })();
    
     //调用匿名对象
     ({
        name: "foo",
        show: function() {
          console.log(this.name);
       }
      }).show();
    console.log({a:
    1}.a); console.log({a: function() {}}.a());

    多种函数立即表达式的写法

    //最常用的两种写法
    (function(){ /* code */ }()); // 推荐写法
    (function(){ /* code */ })(); // 当然这种也可以
    
    // 括号和JS的一些操作符(如 = && || ,等)可以在函数表达式和函数声明上消除歧义
    // 如下代码中,解析器已经知道一个是表达式了,于是也会把另一个默认为表达式
    // 但是两者交换则会报错
    var i = function(){ return 10; }();
    true && function(){ /* code */ }();
    0, function(){ /* code */ }();
    
    // 如果你不怕代码晦涩难读,也可以选择一元运算符
    !function(){ /* code */ }();
    ~function(){ /* code */ }();
    -function(){ /* code */ }();
    +function(){ /* code */ }();
    
    // 你也可以这样
    new function(){ /* code */ }
    new function(){ /* code */ }() // 带参

    立即表达函数带参数

    (function (n){
          console.log(n); // 100
    })(100);

    最好在立即表达函数前面添加分号

     var k=100
    (function (n){
          console.log(n);
    })(k);
    // 出错,解释器会认为100是函数
    var k=100
    ;(function (n){
             console.log(n);
    })(k);

      

      IIFE的形变

    (function(n){
         console.log(n);
                
         //认为这里有30000代码
                
    }(100));

    如果中间有很长的代码,参数100只有到文档的末尾才可以看得到,变形后的结果:

    (function(exp){
           exp(100);
    }(function(n){
           console.log(n);
           //认为这里有30000代码
    }));
  • 相关阅读:
    在python中处理XML
    正则表达式
    python 反射
    python模块概况,json/pickle,time/datetime,logging
    python装饰器
    python3内置函数详解
    python函数,lambda表达式,三目运算,列表解析,递归
    python数据类型及其常用方法
    python3的文件操作
    初识Docker
  • 原文地址:https://www.cnblogs.com/yangWanSheng/p/11708562.html
Copyright © 2020-2023  润新知