函數(shù)表達(dá)式

函數(shù)表達(dá)式

  • 函數(shù)聲明 sample:

      function functionName(arg0,agr1){
        //contents
      }
    

    函數(shù)聲明會把函數(shù)聲明提前。函數(shù)聲明不要寫在if for循環(huán)等代碼塊中,如果一定要
    在if語句或者循環(huán)語句中定義函數(shù)可以用函數(shù)表達(dá)式的辦法。

  • 第二種方法:函數(shù)表達(dá)式 sample:

      var functionName = function(agr0,arg1,arg2){
        //contents
      };
    

    函數(shù)表達(dá)式?jīng)]有聲明提前的效果,所以必須先賦值,再使用。像變量一樣。

  • 遞歸 建議使用命名函數(shù)表達(dá)式
    建議使用下面的例子遞歸 sample:

      var factorial = function f(num){
        if (num <= 1){
          return 1;
        } else {
          return num * f(num - 1);
        }
      }
      factorial(4);//24
    
  • 閉包 閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。創(chuàng)建閉包的常見方式,就是在
    一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)。
    sample:

      function createComparisonFunction(propertyName){
        return function(obj1,obj2){
          var val1 = obj1[propertyName];    
          var val2 = obj2[propertyName];
          if (val1 < val2){
            return -1;
          } else if (val1 > val2){
            return 1;
          } else {
            return 0;
          }
          
        };
      }
    

    上面這個(gè)例子中內(nèi)部匿名函數(shù)可以訪問外部的propertyName,是因?yàn)?br> 內(nèi)部函數(shù)的作用域鏈中包含createComparisonFunction()的作用域。
    再舉個(gè)例子
    sample:

      function compare(val1,val2){
        if(val1>val2){
          return 1;
        } else if ( val1 > val2 ){
          return -1;
        } else {
          return 0;
        }
        
      }
      var result = compare(5,10);
    

    作用域鏈如下所示:

    作用域鏈.jpg

后臺的每個(gè)執(zhí)行環(huán)境都有一個(gè)用來表示變量的對象---變量對象。

而全局的變量對象始終存在,而函數(shù)的局部環(huán)境的變量對象,只有在
函數(shù)的執(zhí)行時(shí)存在。在創(chuàng)建compare()函數(shù)時(shí),會創(chuàng)建一個(gè)預(yù)先包含
全局變量對象的作用域鏈。這個(gè)作用域鏈保存在內(nèi)部的[[Scope]]
屬性中。當(dāng)調(diào)用compare()函數(shù)時(shí),會為函數(shù)創(chuàng)建一個(gè)執(zhí)行環(huán)境,然后通過
復(fù)制函數(shù)[[Scope]]屬性中的對象構(gòu)建起執(zhí)行環(huán)境的作用域鏈。此后又有
一個(gè)活動對象被創(chuàng)建并推入執(zhí)行環(huán)境作用域鏈的前面。對于這個(gè)例子來說
,其作用域鏈中包含兩個(gè)變量對象:本地活動對象和全局變量對象 。
當(dāng)在函數(shù)中訪問一個(gè)變量時(shí),就會從作用域鏈中搜索具有相應(yīng)名字的變量,一般來說
當(dāng)函數(shù)執(zhí)行完畢后,局部活動對象就會被銷毀,內(nèi)存中僅保存娟娟作用域(全局執(zhí)行環(huán)境的變量對象)
但閉包就不一樣了。
內(nèi)部函數(shù)會把外部函數(shù)的活動對象添加到它的作用域鏈中,因此,
在createComparisonFunction()函數(shù)內(nèi)部定義的匿名函數(shù)的作用域鏈中,會包含外部
函數(shù)createComparsionFunction()的活動對象

  var compare = 函數(shù)createComparsionFunction('name');
  var result = compare({ name: "Tom" },{ name: "Jerry" });

在匿名函數(shù)從createComparisonFunction()中被返回后,它的作用域鏈被初始化為
包含createComparsionFunction()函數(shù)的活動對象和全局變量對象。這樣匿名函數(shù)就可以訪問在
createComparisonFunction()中定義的所有變量了。而且更重要的是,外部函數(shù)在執(zhí)行完畢后,
其活動對象也不會被銷毀,因?yàn)閮?nèi)部匿名函數(shù)仍然在引用這個(gè)活動對象。直到匿名函數(shù)被銷毀,外部函數(shù)
的活動對象才會銷毀。

作用域鏈2.jpg

所以閉包會占用內(nèi)存,要合理使用閉包。

function createFunctions(){
  var result = new Array();
  for (var x=0; x < 10; x++){
    result[x] = function(){
    return x*3;
    };
  }
  return result;
}
var z = createFunctions();
z[2]();//30
z[7]();//30

原本希望批量得到一批函數(shù),這些函數(shù)返回三倍的輸入值。但實(shí)際上所有函數(shù)返回的
都是30,也就是最后的x的值10*3。因?yàn)楫?dāng)調(diào)用返回的那個(gè)內(nèi)部匿名函數(shù)的時(shí)候,x的值是循環(huán)
之后的10。
可以改成以下

  function createFunctions(){
    var result = new Array();
    for ( var x = 0;x < 10 ;x++ ){
      result[x] = function(num){
        return function(){
          return num;
        };
      }(x);
    }
    return result;
  }

之所以能成功,是因?yàn)樽罾锩娴哪涿瘮?shù)搜索num時(shí),會找到他外部的函數(shù),而它
外部函數(shù)的num是通過值傳遞進(jìn)去的,每循環(huán)一次num被賦值不同的值。

  • 模仿塊級作用域
    javascript沒有塊級作用域(ES6有了)所以在for循環(huán)外面可以訪問變量i
    可以使用立即調(diào)用匿名函數(shù)的方法模擬塊級作用域從而防止全局變量污染。
      (function(){
        //這里是塊級作用域
      })();
    
    sample:
      function outputNumbers(count){
        (function () {
          for (var i=0 ; i< count;i++){
            alert(i);
          }
        })();
        alert i;//報(bào)錯(cuò),未定義的變量。
      }
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • ??函數(shù)表達(dá)式是 JavaScript 中的一個(gè)既強(qiáng)大有容易令人困惑的特性。定義函數(shù)的的方式有兩種: 函數(shù)聲明; ...
    霜天曉閱讀 831評論 0 1
  • 定義函數(shù)的方式有兩種:函數(shù)聲明和函數(shù)表達(dá)式。 函數(shù)聲明的一個(gè)重要特征就是函數(shù)聲明提升,意思是在執(zhí)行代碼前會先讀取函...
    oWSQo閱讀 679評論 0 0
  • 定義函數(shù)的兩種方式 函數(shù)聲明:函數(shù)聲明提升,在執(zhí)行代碼之前會先讀取函數(shù)聲明,意味著可以把函數(shù)聲明放在調(diào)用它的語句后...
    soso101閱讀 325評論 0 0
  • 備孕期間良好的飲食和作息習(xí)慣會讓您幸福一生 現(xiàn)在越來越多的人有不孕不育的問題,而且,即使懷孕上也出現(xiàn)胎兒發(fā)育不良、...
    慈滿天下閱讀 615評論 0 0
  • 今天的天氣很暖和,中午孩子高興地放學(xué)了。吃過午飯孩子練了一會葫蘆絲,我剛好也不怎么忙了,就和孩子聊了一會中午在學(xué)校...
    壯壯_2d73閱讀 518評論 0 0