js認知-函數

1.函數聲明和函數表達式有什么區(qū)別 (*)

  • 寫法上的區(qū)別。

  • 函數聲明,是關鍵字function加函數名

  • 函數表達式是 前面比那里,后面一個匿名函數賦值給變量

  • 解析上的差異

  • 函數聲明有個聲明前置,可以把調用語句寫在函數聲明的前面或者后面都行,因為默認的會把函數聲明放前面去

  • 然而函數表達式就不行,調用語句必須寫在后面,因為函數表達式相當于變量的賦值,只能把變量聲明前置了。

2.什么是變量的聲明前置?什么是函數的聲明前置 (**)

  • 變量聲明前置會默認把變量的聲明放到前面
例如:
console.log(i); //undefined
var i=100;
這個時候console.log(v);會返回undefined,說明這個變量是在它前面就聲明了,這就是變量聲明前置
  • 函數聲明前置會默認把函數聲明放到前面
test1();//我是函數聲明
test2();//test2 is not a function(…)
function test1(){
  console.log('我是函數聲明')
}
var test2=function(){
  console.log('我是函數表達式')
}
調用語句放在了函數聲明前面,但是結果依然是出來的,這就是函數聲明前置,另外函數表達式就沒有這樣的功能,所以前面調用的時候報錯了

3.arguments 是什么 (*)

  • 類似數組,指的是函數的參數,在函數內部默認存在,我們可以通過arguments來調用函數的每個參數,條目的索引從0開始 后面依次。
function yingxiong(){
console.log('英雄:'+arguments[0]);
console.log('技能:'+arguments[1]);
console.log('口號:'+arguments[2]);
}
yingxiong('蓋倫','大寶劍','人在塔在');//得到以下
英雄:蓋倫
技能:大寶劍
口號:人在塔在

4.函數的重載怎樣實現 (**)

  • js函數沒有重載這個概念,因為只要函數名相同,上面的就會被下面的覆蓋,但是js的函數是可以支持無所個參數的,我們可以通過函數arguments來實現重載。
function item(){
var s="";
for(var i=0;i<arguments.length;i++){
   s =s+(arguments[i]+" ");
}
console.log(s);
}

item("項目1","項目2","項目3");//項目1 項目2 項目3 

參考:詳解JS函數重載

5.立即執(zhí)行函數表達式是什么?有什么作用 (***)

  • 簡稱IIFE :immediately-invoked function expression
  • 寫法:將函數聲明用一個括號框起,讓JavaScript引擎將其理解為一個表達式,后面再接括號直接調用。
    (function(){
    //
    })();
    或
    (function(){
    //
    }());
  • 作用:將js代碼包裹在匿名函數中并立即執(zhí)行,保護變量名外部不可見,不必擔心覆蓋的問題而導致變量的污染
    參考

6.什么是函數的作用域鏈 (****)

  • JavaScript中所有的兩都是存在于某一個作用域中,除了全局作用域,每一個作用域都是存在于某個作用域中,在試圖訪問一個變量時JS引擎會從當前作用域開始向上查找知道Global全局作用域停止。
  • 例如:當alert(a);時,JS引擎沿著d的作用域,b的作用域,全局作用域的順序查找,這樣就構成了作用域鏈。
    var a;//全局作用域
    function b(){
        var c;//c位于b函數的作用域
        function d(){
             var e;//e位于函數d的作用域
             alert(a)
     }
    }

7.代碼

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 s=0;
     for(var i=0;i<arguments.length;i++){
       s+=arguments[i]*arguments[i]
     }
     return s;
   }
   sumOfSquares(2,3,4);   // 29
   sumOfSquares(1,3);   // 10

3.如下代碼的輸出?為什么 (難度*)

    console.log(a); //undefined 
    var a = 1;
    console.log(b); //b is not defined
//因為a變量有個提升,當打印a的時候變量a已經聲明但未賦值,而b還未聲明所以報錯
//變量提升如下:
     var a;
     console.log(a); 
     a = 1;
     console.log(b);

4.如下代碼的輸出?為什么 (難度*)

    sayName('world');//hello world
    sayAge(10);//sayAge is not a function(…)
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };
hello world:是因為聲明函數有前置,函數放置的上下順序并不會影響調用
第二個報錯:是因為函數表達式不會前置,這個時候變量sayAge雖然前置了但并不是函數,所以輸入參數會報錯

5.如下代碼的輸出?為什么 (難度**)

    function fn(){}
    var fn = 3;
    console.log(fn);//3,按順序執(zhí)行,當打印fn的時候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){
        var fn2;
       function fn2(){
            console.log('fnnn2');
        }
       console.log(fn2);
       fn2 = 3;
       console.log(fn2); 
       console.log(fn); 
     }
    fn(10);

console.log(fn2);//function fn2(){console.log('fnnn2');} 因為函數聲明前置了,相當于把這個函數賦值給了fn2
console.log(fn2); //3 當打印到這的時候變量fn2已被賦值為3
console.log(fn); 打印整個函數fn(),打印的時候先從局部作用域尋找,發(fā)現沒找到,就從全局作用域尋找,然后打印出外面都函數聲明
console.log('fnnn2');只聲明未調用

7.如下代碼的輸出?為什么 (難度***)

    var fn = 1;
    function fn(fn){
         console.log(fn);
    }
    console.log(fn(fn)); 
  • 變量提升和聲明函數前置后的樣子。
    var fn;
     function fn(fn){
         console.log(fn);
    }
    fn = 1;
    console.log(fn(fn)); //fn is not a  function 
    //這個時候fn已經被賦值為1,不是函數 所以報錯

8.如下代碼的輸出?為什么 (難度**)

    //作用域
    console.log(j);
    //undefined //除了函數其余都沒有局部作用域,所以j這個時候已經聲明并且提升但未賦值
    console.log(i); 
    //undefined//i已經聲明并且前置,但是還未賦值
    for(var i=0; i<10; i++){
        var j = 100;
    }
    console.log(i);//10 for循環(huán)結束得到i=10 所以打印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;
    var fn;
    function fn(){
        var i;
        function fn2(){
            i = 100;
        }
       console.log(i);//undefined 在局部作用域i已經被聲明且提升
        i = 99;
        fn2(); 
        console.log(i); //100 前面fn2();已經被調用執(zhí)行,這個時候i賦值為100
    }
    fn();
    i = 10;
    fn = 20;
    console.log(i);//10 i被賦值位10

10.如下代碼的輸出?為什么 (難度*****)

   var say = 0;
    (function say(n){
        console.log(n); //打印 10 9 8 7 6 5 4 3 2 
      //這是個立即執(zhí)行函數外面的say=0沒有關系,當輸入10調用的時候首先打印10 然后因為這是個遞歸函數,當n<3的時候停止,所以會依次一直打印直到滿足條件停止,所以到2就停止了。
        if(n<3) return;
        say(n-1);
    }( 10 ));
    console.log(say);//0 上面的立即執(zhí)行函數和外面函數已經隔絕 不會有命名覆蓋的問題,可以不理,所以打印結果0

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 函數聲明和函數表達式有什么區(qū)別 (*)解析器會率先讀取函數聲明,并使其在執(zhí)行任何代碼之前可以訪問;函數表達式則必須...
    coolheadedY閱讀 446評論 0 1
  • 工廠模式類似于現實生活中的工廠可以產生大量相似的商品,去做同樣的事情,實現同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 8,116評論 2 17
  • 1.函數聲明和函數表達式有什么區(qū)別 (*) 區(qū)別: 函數聲明后面的分號可加可不加,不加也不影響接下來語句的執(zhí)行,但...
    Sheldon_Yee閱讀 469評論 0 1
  • 問答題 函數聲明和函數表達式有什么區(qū)別 (*)答://函數聲明function hello(){ conso...
    饑人谷_桶飯閱讀 293評論 0 0
  • 問答 函數聲明和函數表達式有什么區(qū)別?函數聲明用指定的參數聲明一個函數,必須有函數名稱,可在函數聲明之前使用函數 ...
    叮叮當當叮叮叮閱讀 217評論 0 0

友情鏈接更多精彩內容