任務(wù)17 函數(shù)-簡答題

1.函數(shù)聲明和函數(shù)表達式的區(qū)別?

  • 在ECMAScript中,創(chuàng)建函數(shù)的最常用的兩個方法是函數(shù)表達式和函數(shù)聲明,兩者期間的區(qū)別是有點暈,因為ECMA規(guī)范只明確了一點:函數(shù)聲明必須帶有標(biāo)示(Identifier)(就是大家常說的函數(shù)名稱),而函數(shù)表達式則可以省略這個標(biāo)示符:
  • 函數(shù)聲明:
    function 函數(shù)名稱(參數(shù):可選){函數(shù)體}
  • 函數(shù)表達式:
    function 函數(shù)名稱(可選)(參數(shù):可選){函數(shù)體}
  • 小結(jié):
  1. 若不聲明函數(shù)的名稱,它就是函數(shù)表達式
  2. 若同時聲明了函數(shù)名稱,ECMAScript是通過上下文來區(qū)分的,如果function foo(){}是作為賦值表達式的一部分的話,例如:var fun1=function foo(){},那它就是一個函數(shù)表達式。如果function foo(){}被包含在一個函數(shù)體內(nèi),或者位于程序的最頂部的話,那它就是一個函數(shù)聲明。
  3. 特殊的函數(shù)表達式,如:(function foo(){}) 它是表達式的原因是因為括號 ()是一個分組操作符,它的內(nèi)部只能包含表達式,同理如,JSON字符串通常被包含在一個圓括號里:eval('(' + json + ')'),這樣做的原因就是因為分組操作符,也就是這對括號,會讓解析器強制將JSON的花括號解析成表達式。

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

  • 所謂的變量聲明前置就是在一個作用域塊中,所有的變量都被放在塊的開始出聲明,下面舉個例子你就能明白了
    1.變量a 在函數(shù)外面
    var a=1;
    function fun1(){
    console.log(a);// 1
    }
    main();//輸出 1

    var a = 1; 
          function fun1(){ 
             console.log(a);
               var a = 2;
         }
          main()//輸出undefined
    

2.同樣是變量a在函數(shù)外層,為什么出現(xiàn)undefined,這是因為JS在執(zhí)行時候,會自動將變量聲明前置,解析步驟如下:
var a=1;
function fun1(){
var a;// a 此時為undefined
console.log(a);//輸出結(jié)果為undefined
a=2;//a 被賦值為2,但沒有輸出
}
fun1();//undefined

  • 和變量的聲明會前置一樣,函數(shù)聲明同樣會前置.
    1.如果我們使用函數(shù)表達式那么規(guī)則和變量一樣;
    console.log(fun1) //undefined
    var fun1= function(){}
    2.我們使用函數(shù)聲明的方式,那么即使函數(shù)寫在最后也可以在前面語句調(diào)用,前提是函數(shù)聲明部分已經(jīng)被下載到本地
    fun1();//結(jié)果為1
    function fun1(){
    console.log(1); //1
    }

3.arguments 是什么?

  • arguments 是是JavaScript里的一個內(nèi)置對象,它很古怪,也經(jīng)常被人所忽視,但實際上是很重要的。所有主要的js函數(shù)庫都利用了arguments對象。所以agruments對象對于javascript程序員來說是必需熟悉的。所有的函數(shù)都有屬于自己的一個arguments對象,它包括了函所要調(diào)用的參數(shù)。他不是一個數(shù)組,如果用typeof arguments,返回的是'object'。雖然我們可以用調(diào)用數(shù)據(jù)的方法來調(diào)用arguments。比如length,還有index方法。但是數(shù) 組的push和pop對象是不適用的
  • 在函數(shù)內(nèi)部,你可以使用arguments對象獲取到該函數(shù)的所有傳入?yún)?shù)
    function info(name,sex,age){
    console.log(name);//"小明"
    console.log(sex);//"男"
    console.log(age);//18
    console.log(arguments[0]);//"小明"
    console.log(arguments[1]);//"男"
    console.log(arguments[2]);//18
    console.log(arguments);//"小明","男",18
    console.log(arguments.length)//3
    }
    info("小明","男",18);//
    info("小明","男");// “小明”,“男”,undefined 2
    瀏覽器輸出結(jié)果:
    ![3BXV%DI)S@R8EB2@$NL26F.png

4. 函數(shù)的重載怎樣實現(xiàn)

  • 重載是很多面向?qū)ο笳Z言實現(xiàn)多態(tài)的手段之一,在靜態(tài)語言中確定一個函數(shù)的手段是靠方法簽名——函數(shù)名+參數(shù)列表,也就是說相同名字的函數(shù)參數(shù)個數(shù)不同或者順序不同都被認(rèn)為是不同的函數(shù),稱為函數(shù)重載
  • 在JavaScript中沒有函數(shù)重載的概念,函數(shù)通過名字確定唯一性,參數(shù)不同也被認(rèn)為是相同的函數(shù),后面的覆蓋前面的
  • 在js中,我們實現(xiàn)重載常用的方式有:
    1、根據(jù)傳入?yún)?shù)的類型執(zhí)行不同的操作。
    2、利用參數(shù)中特殊的參數(shù)值進行不同的操作。
    3、根據(jù)參數(shù)的個數(shù)進行重載。
    這里對第3種實現(xiàn)方式進行說明
    function f(length) {
    var len= arguments.length;
    if(1 == len) {
    var width = arguments[1];
    alert("高為:"+length+",寬為:"+width);
    } else {
    alert("高為:"+length);
    }
    }
    f(10);// 高為10
    f(10,10);高為10,寬為10
    你就可以給函數(shù)f()傳入一個參數(shù)也可以傳入兩個參數(shù)了

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

  • 立即執(zhí)行函數(shù)就是聲明一個匿名函數(shù),馬上調(diào)用這個匿名函數(shù)
  • 立即執(zhí)行函數(shù)表達式有兩種寫法
  1. 第一種
    (function(){ }());
  2. 第二種
    (function(){ })();
  • 只有一個作用:創(chuàng)建一個獨立的作用域。這個作用域里面的變量,外面訪問不到(即避免「變量污染」),例如:
    var liList = ul.getElementsByTagName('li')
    for(var i=0; i<6; i++){
    liList[i].onclick = function(){
    alert(i) // 為什么 alert 出來的總是 6,而不是0、
    1、2、4、5
    }
    }
    這是因為i貫穿了整個作用域,而在js中除了函數(shù)內(nèi)有作用域,{ }里的內(nèi)容不是作用域,因而for運行完后i的值為6,而用戶也是在for運行完才點擊,此時i為6。
    解決整個問題就要立即執(zhí)行函給每個li創(chuàng)造獨立的作用域
    var liList = ul.getElementsByTagName('li')
    for(var i=0; i<6; i++){
    !function(li){
    liList[li].onclick = function(){
    alert(li) // 0、1、2、3、4、5
    }
    }(i)
    }
    在立即執(zhí)行函數(shù)執(zhí)行的時候,i 的值被賦值給 ii,此后 ii 的值一直不變。i 的值從 0 變化到 5,對應(yīng) 6 個立即執(zhí)行函數(shù),這 6 個立即執(zhí)行函數(shù)里面的 ii 「分別」是 0、1、2、3、4、5。

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

  • 作用域鏈?zhǔn)谴鎯?strong>變量對象的集合(環(huán)境棧),保證對執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問,也就是用于標(biāo)識符解析(變量訪問)。
  • 在javascript沒有塊級作用域,是由函數(shù)來劃分的。變量和函數(shù)的作用域是在定義時決定而不是執(zhí)行時決定,也就是說詞法作用域取決于源碼,通過靜態(tài)分析就能確定,因此詞法作用域也叫做靜態(tài)作用域(with和eval除外)。當(dāng)定義了一個函數(shù),當(dāng)前的作用域鏈就保存起來,并且成為函數(shù)的內(nèi)部狀態(tài)的一部份。在最頂級作用域鏈僅由全局對象組成,而不和詞法作用域相關(guān),然而,當(dāng)定義一個嵌套的函數(shù)時,作用域鏈就包括外面的包含函數(shù)。這意味著嵌套函數(shù)可以訪問包含函數(shù)的所有參數(shù)和局部變量。盡管當(dāng)一個函數(shù)定義時作用域鏈就固定了,但作用域鏈中定義的屬性還沒有固定。作用域鏈?zhǔn)腔畹?,并且函?shù)被調(diào)用時,可以訪問任何當(dāng)前的綁定。
    var a;//全局作用域
    function b(){
    var c ;//c位于函數(shù)b的作用域
    function d(){
    var e; //e位于函數(shù)d的作用域
    alert(a);
    }
    }
  • 當(dāng)alert(a)時,jsJS引擎沿著d的作用域, b的作用域, 全局作用域的順序進行查找,這三個作用域組成的有序集合就成為作用域鏈
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 (*)解析器會率先讀取函數(shù)聲明,并使其在執(zhí)行任何代碼之前可以訪問;函數(shù)表達式則必須...
    coolheadedY閱讀 445評論 0 1
  • 問答題 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 (*)答://函數(shù)聲明function hello(){ conso...
    饑人谷_桶飯閱讀 293評論 0 0
  • 問答: 1. 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 (*) 在日常的任務(wù)中,JavaScript主要使用下面兩種方式創(chuàng)建...
    小木子2016閱讀 388評論 0 0
  • 2016-0907 今天早晨起來一早上無話,自己默默的做些事情,突然這樣也覺得很好。 買早餐的時候室友飯卡里錢不夠...
    冰美式咖啡閱讀 205評論 1 1

友情鏈接更多精彩內(nèi)容