任务17

作者: 璐璐熙可 | 来源:发表于2016-11-04 16:04 被阅读21次

    问答

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

    函数声明:


    函数表达式:


    函数声明:函数调用可以发生在函数声明之前,例如下面这种情况下不会报错


    函数表达式:函数调用只能在函数表达式后面,不能在函数表达式前面,例如下面这种情况就会报错


    综上所述函数声明和函数表达式的区别是:
    函数声明会产生函数的声明前置,因此可以把函数的调用写在函数声明之前;但函数表达式只能产生变量的声明前置,如果把调用放在函数表达式之前则会报错。
    函数声明语句之后不加分号;函数表达式是一个语句结尾需加分号。

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

    • 变量声明前置:
      程序在执行前,会提取程序中var声明的变量,但不提取赋值,叫变量声明前置,如下图所示



      上面的代码等同于:

    var age;
    console.log(age);//此时age被声明但没有被赋值,所以结果为undefined;
    age=10;
    
    • 函数的声明前置:
      javaScript解释器允许在函数声明之前调用函数,此时不仅仅是函数名被前置了,整个函数定义也被前置了,所以就可以直接调用函数,如下图所示


    3.arguments 是什么?

    在函数内部,可以使用arguments对象获取到该函数的所有传入参数,类似数组.

    function printPersonInfo(name, age, sex) {
        console.log(name);
        console.log(age);
        console.log(sex);
        console.log(arguments);
    }
    printPersonInfo('liu', 18, 'nan');
    
    输出的结果为:

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

    在JS中没有函数重载的概念,函数通过名字确定唯一性,参数不同也被认为是相同的函数,后面的覆盖前面的。所以只要在函数体内做好处理就行。

    function sum(a,b){
        console.log(a+b);
    }
    function sum(a,b,c){
        console.log(a+b+c);
    }
    sum(1,4,5);
    
    最后的结果为10.
    

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

    立即执行函数表达式:指的是不需要进行函数的调用立即执行,可以将写在函数体内的语句立即执行。

    function  name() {
        console.log('lulu');
    }
    name();
    //这种写法必须通过name()调用后才可以执行,function name(){}只是声明这个函数,并没有执行。
    
    //我们可通过对整个函数加小括号来使函数声明变成函数表达式,从而立即执行:
    有两种写法:
    (function name() {
       console.log('lulu');
    })();
    或
    (function name() {
        console.log('lulu');
    }());
    
    

    作用:让这段代码拥有自己的作用域,主要是这是一个表达式,所以不会前置,而且立即执行后,在其他地方也无法调用.

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

    函数的作用域链指的是:js中的作用域在函数里形成,我们在执行代码过程中,函数里可以使用函数中定义的变量,如果函数里没声明这个变量,它会直接访问到这个函数作用域外的全局变量.

    for(var i=0; i<10; i++){
        var j=200;
    }
    //for循环无作用域,它没有局部作用域;
    function k() {
        console.log(i);//程序在执行前,会提取程序中var声明的变量,但不提取赋值,这就是变量的声明前置,结果为undefined.
        var i=100;
        function k2() {
            i=99;//此时i没被声明,就从它的上一级去找被声明的变量i.
        }
        k2();
        console.log(i);//从它的上一级找到了var i=100;因为函数k2中的i赋值为99,所以把99赋给我们再上一级中找到的的var i=100,也就是此时var i=99;所以最后输出的结果为99;
    }
    k();
    console.log(i);//没加var相当于声明全局变量.for循环中的i的结果为10,所以此时的结果为10;
    

    代码

    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, "男"]
    //name:valley
    
    getInfo('hunger', 28);
    //name:hunger
    //age:28
    //sex:undefined
    //["hunger", 28]
    //name:valley
    
    getInfo('男');
    //name:男
    //age:undefined
    //sex:undefined
    //["男"]
    //name:valley
    

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

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

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

    console.log(a);//程序在执行前,会提取程序中var声明的变量,但不提取赋值,这就是变量的声明前置,结果为undefined.
    var a = 1;
    console.log(b);//报错b is not defined,变量b没有被声明所以报错;
    

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

    sayName('world');
    sayAge(10);
    function sayName(name){
        console.log('hello', name);//hello world 由于存在函数声明前置的现象,所以在此调用之前函数sayName已经声明完毕,可以正常调用。
    }
    var sayAge = function(age){
        console.log(age);//报错:sayAge is not a function,因为sayAge是一个函数表达式,所以遵从的是变量的声明前置。但虽然声明前置,但赋值仍在此调用之后。所以sayAge被当成一个普通变量而非函数进行处理,因此这里作为函数进行调用时会报错。
    };
    

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

    function fn(){}
    var fn = 3;
    console.log(fn);
    等价于
    var fn;//因为变量声明的优先级高于函数声明所以先变量声明再函数声明
    function fn(){}
    fn=3;//fn赋值为3;
    console.log(fn);//结果为3,当在同一个作用域内定义了名字相同的变量和方法的话,无论其顺序如何,变量的赋值会覆盖方法的赋值;
    

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

    function fn(fn2){
           console.log(fn2);
           var fn2 = 3;
           console.log(fn2);
           console.log(fn);
           function fn2(){
           console.log('fnnn2');
            }
         }
    fn(10);
    
    上述代码可以转换为如下代码:
    function fn(fn2) {//在函数fn()的局部作用域下,函数fn2()和变量fn2都提升到该作用域的顶部.
        var fn2;//声明变量
        function fn2() {//声明函数
            console.log('fnnn2');//由于函数fn2()与变量fn2重名,函数执行时载入的顺序是变量,函数,参数;函数覆盖变量,所以得到的是函数fn2()极其函数体内部的代码.
        }
        console.log(fn2);
        fn2=3;
        console.log(fn2);//fn2此时被赋值为3,输出结果为3
        console.log(fn);//在函数的作用域中找不到fn,所以会在全局中找,所以会输出整个fn函数.
    }
    fn(10);
    

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

    var fn = 1;
        function fn(fn){
             console.log(fn);
        }
    console.log(fn(fn)); 
    

    上面的代码等价于

    var fn;
        function fn(fn){        // 声明名为fn的函数,并且有一个fn的参数
            console.log(fn);    
        }
        fn = 1;                 // fn不再是函数,变成1
        console.log(fn(fn));    // 此时fn是1,即number类型。不再是函数,所以报错,fn is not a function
    

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

    //作用域
        console.log(j);//undefined jS中只有函数才具有作用域,普通循环语句不会改变作用域,循环体内变量提升未被赋值;
        console.log(i);//undefined同上
        for(var i=0; i<10; i++){
            var j = 100;
        }//循环结束时候i=10;j=100;
        console.log(i);//10 执行循环后i值变为10
        console.log(j);//100 循环体里j的值是100
    

    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;//变量i声明前置
    var fn;//变量fn声明前置
    function  fn() { //定义一个函数fn
      var i;//函数fn中先声明i
      function fn2() { //再定义函数fn2
          i=100;
     }
    console.log(i);//因为此时fn2()函数没有被调用,所以i没有被赋值,i仅被声明但没有赋值,所以输出结果为undefined
        i=99;//i赋值为99
        fn2();//此处调用了fn2()函数,但是函数fn2中的i赋值为100
        console.log(i);//此时输出结果为100
    }
    fn();
    i=10;//此处i被重新赋值为10
    fn=20;
    console.log(i);//此时输出结果为10
    

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

    var say = 0;
    (function say(n){//立即执行函数
        console.log(n);//初始传递的参数是10,第一次输出的结果为n=10,满足n<3这个条件,此时执行say(n-1);依此类推
        if(n<3) return;//当n=2时不满足条件,return跳出
        say(n-1);
    }( 10 ));
    console.log(say);//全局作用域中say=0,输出0;
    依次输出:10,9,8,7,6,5,4,3,2,0
    因为函数为立即执行函数,变量只在函数作用域内生效,并不会影响到函数作用域外的变量.所以最后console.log(say)输出0.
    

    相关文章

      网友评论

          本文标题:任务17

          本文链接:https://www.haomeiwen.com/subject/hkcwuttx.html