任务17-函数

问答题

  • 函数声明和函数表达式有什么区别 (*)
    答:

    //函数声明
    function hello(){
        console.log("hello world");
    }
    
    //函数表达式
    var hello = function(){
        console.log("hello world");
    }
    
    

    两种方式都能声明函数,但是函数声明的写法会将函数前置,可以在全局种任何地方调用函数;但是表达式只能前置sayHi变量,如果在表达式之前调用函数则会报错,只能放在表达式后面进行调用。

  • 什么是变量的声明前置?什么是函数的声明前置 (**)
    答:

    • 变量的声明前置:变量声明都会被放在代码的头部,只提升变量的声明并不会进行赋值。
    //全局中定义变量
    var a = 1;
    var b = 2;
    //实际是执行起来是这样的
    var a;
    var b;
    a = 1;
    b = 2;
    
    //函数中
    function say(){
        var a = 1;
        console.log(a);
        var b = 2;
    }
    //实际运行过程
    function say(){
        var a;
        var b;
        a = 1;
        console.log(a);
        b = 2;
    }
    
    • 函数声明前置:函数的声明前置和变量声明一样,会提升到代码头部。但是会提升到变量声明后面,所以可以在函数声明前面调用函数。
     f(10);//10     此时该函数是有效的,且结果正确
    function f(num){
        console.log(num);
    }
    

    相当于

    function f(num){
       cconsole.log(num);
    }
    f(10);
    
  • arguments 是什么 (*)
    答:
    Arguments是个类似数组但不是数组的对象,说他类似数组是因为其具备数组相同的访问性质及方式,能够由arguments[n]来访问对应的单个参数的值,并拥有数组长度属性length。还有就是arguments对象存储的是实际 传递给函数的参数,而不局限于函数声明所定义的参数列表,而且不能显式创建 arguments 对象。


    Paste_Image.png

    arguments对象的长度是由实参决定的。

  • 函数的重载怎样实现 (**)
    答:
    在JavaScript中没有函数重载的概念,函数通过名字确定唯一性,参数不同也被认为是相同的函数,后面的覆盖前面的。函数调用没必要把所有参数都传入,只要你函数体内做好处理就行,但前提是传的参数永远被当做前几个。


    Paste_Image.png
  • 立即执行函数表达式是什么?有什么作用 (***)
    答:

    (function(){
        //第一种
    })();
    
    (function(){
        //第二种
    }());
    

    作用是:立即执行函数可以避免函数内的变量暴露在全局环境下,避免全局变量的污染。可以令其函数中声明的变量绕过JavaScript的变量置顶声明规则,还可以避免新的变量被解释成全局变量或函数名占用全局变量名的情况,在函数内部内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。

  • 什么是函数的作用域链 (****)
    答:
    在一个函数执行过程中如果某个变量在该函数自己的作用域中没有,那么它会寻找父级的作用域,直到全局作用域,这样就形成了一个作用域链。


    Paste_Image.png

    执行ss()时,作用域链是: ss()->t()->window,所以name是”桶饭"

代码题

  1. 以下代码输出什么? (难度**)

        function getInfo(name, age, sex){
        console.log('name:',name);
        console.log('age:', age);
        console.log('sex:', sex);
        console.log(arguments);
        arguments[0] = 'valley';
        console.log('name', name);
    }
    
    getInfo('hunger', 28, '男');
    getInfo('hunger', 28);
    getInfo('男');
    

输出结果:


Paste_Image.png

形参和实参的数量可以不一样,用arguments可以改变实参的值。

  1. 写一个函数,返回参数的平方和?如 (难度**)

       function sumOfSquares(){
       var num;
       for(var i = 0;i<arguments.length;i++){
         
         num = num+arguments[i]*arguments[i];
       }
      return num;
       
    }
     sumOfSquares(2,3,4);   // 29
     sumOfSquares(1,3);
    
  2. 如下代码的输出?为什么 (难度*)

    console.log(a);
    var a = 1;
    console.log(b);
    
    //运算过程
    var a;
    console.log(a);//输出undefined,因为变量提升,会把变量a的声明提升到console.log(a);之前,当console.log(a);执行的时候,变量a还没有被赋值,所以console.log(a);输出undefined。
    a = 1;
    console.log(b);//报错,因为没有变量b。
    

    输出结果:

Paste_Image.png
  1. 如下代码的输出?为什么 (难度*)

    sayName('world');
    sayAge(10);
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };
    
    //运算过程
    //在执行上面代码的时候会将函数的声明前置,而函数表达式只会将变量的声明前置,函数不会前置。实际上述代码在执行的时候会变成这样:
    var sayAge;
    function sayName(name){
        console.log('hello ', name);
    }
    sayName('world');
    sayAge(10);//sayAge(10);的时候,sayAge只是个变量不是函数,所以会报错。最终会输出hello world和报错。
    sayAge = function(age){
        console.log(age);
    };
    
    
    Paste_Image.png
  2. 如下代码的输出?为什么 (难度**)

    function fn(){}
        var fn = 3;
        console.log(fn);//输出3
        //当在同一个作用域内定义了名字相同的变量和方法的话,无论其顺序如何,变量的赋值会覆盖方法的赋值。
    
  3. 如下代码的输出?为什么 (难度***)

        function fn(fn2){
           console.log(fn2);
           var fn2 = 3;
           console.log(fn2);
           console.log(fn);
           function fn2(){
                console.log('fnnn2');
            }
         }
        fn(10);
    

输出:


Paste_Image.png
   //过程
   function fn(fn2){
   
   var fn2;//变量声明前置
   function fn2(){
         console.log('fnnn2');
     }//函数声明前置
   console.log(fn2);//log fn2()函数
   fn2 = 3;//赋值
   console.log(fn2);//log fn2  此时 fn2是3
   console.log(fn);//此作用域找不到 fn,向上寻找打印 fn 函数
   
   }
   fn(10);
   //函数执行命名有冲突的时候,函数执行载入顺序是变量、函数、参数
   ```

7. 如下代码的输出?为什么 (难度***)

   ```
   var fn = 1;
   function fn(fn){
       console.log(fn);
   }
   console.log(fn(fn)); 
   ```
   输出:
   ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2858982-ab080b605e1f5adb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

   因为给变量声明进行赋值操作后,同名的变量声明的优先级会大于同名函数声明,会覆盖同名的函数声明,所以fn现在是一个变量不是函数,执行函数fn就会报错。

8. 如下代码的输出?为什么 (难度**)

   ```
   //作用域
   console.log(j);//输出undefined,因为变量声明前置,i这时候还没有赋值。
   console.log(i);//输出undefined,因为变量声明前置,j这时候还没有赋值。
   for(var i=0; i<10; i++){
      var j = 100;
   }
   console.log(i);//输出10,因为for循环语句结束循环时,i的值是10 。
   console.log(j);//输出100,应为变量j的值是100。
   ```
   输出:
   ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2858982-dad462fcdf2280d3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

9. 如下代码的输出?为什么 (难度****)

   ```
   fn();
   var i = 10;
   var fn = 20;
   console.log(i);
   function fn(){
      console.log(i);
      var i = 99;
      fn2();
      console.log(i);
      function fn2(){
          i = 100;
      }
   }
   ```
   
   ```
   //过程
   var i;
   var fn;
   
   function fn() {
   
      var i;
   
      function fn2() {
          i = 100;
      }
      console.log(i);// 输出undefined,因为变量i的声明前置,但还没有赋值。
      i = 99;
      fn2();//执行函数fn2,因为函数中的变量i没有加关键字var,所以它是一个全局变量,它会把100赋值到函数fn的变量i。这时i=100
      console.log(i);//输出100,因为变量i的值为100。
   }
   fn();
   i = 10;
   fn = 20;
   console.log(i);//输出10,因为最后变量i的值是10。
   ```
   ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2858982-a755443ab6d14c20.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

10. 如下代码的输出?为什么 (难度*****)

   ```
   var say = 0;
   (function say(n){ //立即执行函数,给函数初始的参数n=10,当满足n<3时,执行say(n-1)。
      console.log(n);//输出10,9,8,7,6,5,4,3,2,因为当n=2时,函数return。
      if(n<3) return;
      say(n-1);
   }( 10 ));
   console.log(say);//输出0.因为立即执行函数say(n)相当于创造了一块私有的作用域,函数say(n)内部可以访问外部的变量,而外部环境不能访问函数say(n)内部的变量,内部定义的变量不会和外部的变量发生冲突,所以变量say一直等于0。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.函数声明和函数表达式有什么区别 (*) 函数声明 函数表达式 函数声明:函数调用可以发生在函数声明之前,例如下...
    TimeLesser阅读 403评论 4 4
  • 问答: 1. 函数声明和函数表达式有什么区别 (*) 在日常的任务中,JavaScript主要使用下面两种方式创建...
    小木子2016阅读 330评论 0 0
  • 函数声明和函数表达式有什么区别 (*)解析器会率先读取函数声明,并使其在执行任何代码之前可以访问;函数表达式则必须...
    coolheadedY阅读 400评论 0 1
  • 1.函数声明和函数表达式的区别? 在ECMAScript中,创建函数的最常用的两个方法是函数表达式和函数声明,两者...
    GarenWang阅读 547评论 0 0
  • 关于模仿 看到这个词,你的第一反应是什么? 反感? 厌恶? 嗤之以鼻? 冷静下来!思考一下,哪个人能离开这个词? ...
    淡定的小孩儿阅读 218评论 0 2