## 函数

1.函数声明和函数表达式有什么区别

  • 声明方式不同:
    • 函数声明:function lol(参数(可选)){函数体};函数声明会前置
    • 函数表达式:var a = function函数名称可选参数(可选)){函数体};还有一种常见函数表达式:(function () { })(),表示立即执行,常用于匿名函数的调用。函数表达式不会前置

2.什么是变量的声明前置?什么是函数的声明前置

  • 变量的声明前置:
    console.log(a)//输出undefined,虽然此处a尚未出现,但声明已经前置,即var a,赋值的动作并不会前置
    var a = 1;
  • 函数的声明前置:js解析器会首先解析函数声明,确保所有代码执行之前已经全部被解析,无论在哪里调用此函数都会执行
    a()
    function a(){
    console.log (ok) }//这是函数声明,会被单独前置
    和下面代码等价
    function fuc(){
    console.log (ok) }
    fuc();

3.arguments 是什么 ?

  • arguments是一个包含函数运行时的所有参数的对象,只有在函数开始时才可用,不能被显式创建,可通过arguments[i]依次对参数进行访问和修改,与数组元素的方式相同,但并不是一个数组。

4.函数的重载怎样实现?

  • 在JavaScript中没有函数重载的概念,函数通过名字确定唯一性,参数不同也被认为是相同的函数,后面的覆盖前面的,可通过length属性提供了一种机制,判断定义时和调用时参数的差异,实现面向对象编程的”方法重载“(overload)。 (函数名.length=形参长度),根据判断语句,然后传递不同数量的参数,来实现一种类似重载的效果。但声明函数的时候就不能将形参的个数具现化,因为这样的话,传入的实参个数如果与形参不等,便会报错

5.立即执行函数表达式是什么?有什么作用

  • 立即执行函数表达式本质上是一个表达式,可以让你的函数在定义后立即被执行
  • 书写方式:
    (function fx(){
    console.log('name');
    }());
  • 作用:隔离作用域,立即执行函数定义的所有变量都会成为函数的局部变量,所以不用担心这些临时变量会污染全局空间
  • 立即执行函数可以让你将独立的功能封装在自包含模块中,而不会影响其他模块。

6. 什么是函数的作用域链

  • 任何执行上下文时刻的作用域, 都是由作用域链来实现.
  • 当一个函数被声明的时候,会给这个函数添加一个scope属性.
  • 在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参,都命名为该活动对象的命名属性, 然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope chain中.
  • 作用域链的原理和原型链很类似,如果这个变量在自己的作用域中没有,那么它会寻找父级的,直到最顶层。

代码题:

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, '男');    
           //name:hunger
           //age:28
           //sex:男
           //['hunger',28,'男'](arguments会输出所有传入的实参,这是个类数组对象)
           //给第一位重新赋值‘valley’  ,输出name :valley
          getInfo('hunger', 28); 
           //name:hunger
           //age:28
           //undefined
           //[‘hunger’,28]
           //给第一位重新赋值‘valley’  ,输出name valley
          getInfo('男');
           //name:男
           //undefined
           //undefined
           //['男']
           //给第一位重新赋值‘valley’  ,输出name valley

2.写一个函数,返回参数的平方和?

       function sumOfSquares(){
            var result = 0;
            for(var i = 0;i < arguments.length; i++){
                   var sum = arguments[i]*arguments[i]; 
                   result += sum;
            };
           return result;
       }
       sumOfSquares(2,3,4);   // 29
       sumOfSquares(1,3);   // 10

3.如下代码的输出?

     console.log(a); //undefined,`声明前置`,但值没有前置,此处只是有a的声明,但未初始化。
     var a = 1; //此处为a赋值,约等于`a=1`,没有输出。
    console.log(b);//b is not defined,因为未对b做出声明。

4.如下代码的输出?为什么

      sayName('world');//输出“`hello world`”,因为如果用函数声明的方式定义的函数,卸载哪里都会被调用。
      sayAge(10); //报错,sayAge是用函数表达式定义的,变量提升,即此处sayAge只是一个变量,而sayAge(10)是以函数调用的形式出现,因此报错。
     function sayName(name){ 
              console.log('hello ', name); 
     } 
     var sayAge = function(age){ 
              console.log(age); 
     };

5.如下代码的输出?为什么

     function fn(){
    } 
    var fn = 3; 
    console.log(fn);//输出3,虽然变量与函数都会被提升,但名为`fn`的函数首先会覆盖掉名为`fn`的变量,但紧接着,fn被赋值为3,所以输出3。

6.如下代码的输出?为什么

     function fn(fn2){
            console.log(fn2);//function fn2(){console.log('fnnn2');} 因为函数声明和变量声明均会被前置, 但同名函数会覆盖变量,因此,此时的`fn2`是函数。
            var fn2 = 3; //接着fn2被赋值为3.
            console.log(fn2); //3 ,上一步已将fn2变为3。
            console.log(fn); //输出整个fn函数 因为fn定义为函数 在函数内部是有效的
            function fn2(){ 
                    console.log('fnnn2'); // 原因1:不会输出 因为fn2 已经被覆盖。原因二: 哪怕是函数,也没有调用,因此不会执行。
               }
          } 
       fn(10);

7.如下代码的输出

        var fn = 1; 
        function fn(fn){
           console.log(fn); 
         } //此时`var fn `已经形同虚设,被同名函数所覆盖。但紧接着,`fn = 1`,`fn`又称为一个值暂时未1的变量。
       console.log(fn(fn));//上一步后,fn已经为1,不是函数,因此,以函数调用的方式`fn()`访问会报错。

8.以下代码如何输出?

        console.log(j);//undefined,声明前置
        console.log(i); //undefined,声明前置
        for(var i=0; i<10; i++){
                     var j = 100;
         } 
        console.log(i);//10,i>=10才会跳出循环。
        console.log(j);//100,j和此处打印语句均在一个作用域内。

9.以下代码如何输出?

       fn();                               变量、函数提升后: var i;
       var i = 10;                                                  var fn;
       var fn = 20;                                                function fn(){ 
       console.log(i);                                                var i;
       function fn(){                                               function fn2(){
              console.log(i);                                          i = 100;  
              var i = 99;                                              };
              fn2();                                                 console.log(i);//i未赋值。输出underfined。
              console.log(i);                                        i = 99;//i赋值99
              function fn2(){                                        fn2();//执行fn2()。i赋值为100.
              i = 100;                                               console.log(i);//100,上一步得到结果。
              }                                                          }
       }                                                             fn();//执行fn()。
                                                                     i = 10;//i赋值10.
                                                                     fn = 20;
                                                                     console.log(i);//输出10.

10.如下代码的输出?为什么

        var say = 0;
        (function say(n){ 
              console.log(n); //立即执行函数,尾部给n赋值10,然后执行下边if语句,每过一次,就会输出一个值,直到n=3,还执行一次,因此,输出10.9.8.7.......2
              if(n<3) return; 
              say(n-1);//递减操作
              }( 10 )); 
       console.log(say);//外部不会受到内部函数影响,因此,输出0
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,529评论 6 524
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,683评论 3 406
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,905评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,318评论 1 303
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,325评论 6 401
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,754评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,081评论 3 431
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,088评论 0 280
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,653评论 1 327
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,651评论 3 347
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,766评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,359评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,083评论 3 341
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,491评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,654评论 1 278
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,367评论 3 383
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,836评论 2 367

推荐阅读更多精彩内容

  • 函数声明和函数表达式有什么区别 (*)解析器会率先读取函数声明,并使其在执行任何代码之前可以访问;函数表达式则必须...
    coolheadedY阅读 393评论 0 1
  • 1.函数声明和函数表达式有什么区别 (*) 区别: 函数声明后面的分号可加可不加,不加也不影响接下来语句的执行,但...
    Sheldon_Yee阅读 403评论 0 1
  • 1. 函数声明和函数表达式有什么区别? 在变量提升或声明提前过程中,函数声明是将整个被定义的函数提前,即该函数可以...
    王康_Wang阅读 389评论 0 0
  • 问答题 函数声明和函数表达式有什么区别 (*)答://函数声明function hello(){ conso...
    饥人谷_桶饭阅读 246评论 0 0
  • 一个风和日丽的周末,在工作之余,约上好友,放松一下,望北京内外,除后海再无他海,而北戴河又是离北京最近的海边旅游城...
    小丸子爱吃鱼呀阅读 1,691评论 2 1