天天看點

函數表達式-JS高程函數表達式

函數表達式

  1. 定義函數的方式有兩種:
    1. 函數聲明
    sayHi();  
    function sayHi() {  
        alert('hi');  
    }
               
    1. 函數表達式
    var functionName = function(a,b,c){}
               
  2. 注意
    1. 匿名函數
    2. 使用前必須先指派
//錯誤代碼  
    sayHi();  
    var sayHi = function() {  
        alert('hi');  
    }  
    //另一個例子  
    var sayHi;  //如果不指派在js中屬于無效文法  
    if(condition) {  
    sayHi = function() { alert('hi');}  
    }else {  
    sayHi = function() { alert('aha');}  
    }
           

遞歸

  1. 問題1
    var diguiA = digui;  
    digui = null;  
    alert(diguiA(4));
               
  2. arguments.callee

    是一個指向正在執行的函數的指針,以此來替代函數名,調用函數。

  3. 問題2

    嚴格模式下,通路這個屬性會産生錯誤

  4. 解決(命名函數表達式)
    var digui = (function d(num) {  
        if (num <= 1) {  
        return  1;  
        } else {  
        return num * f(num-1);  
        }  
    })
               

閉包

有權通路另一個函數作用域中的變量的函數。

建立閉包的常用方式,就是在一個函數内部建立另一個函數。

function out(outX) {  
    return function (object1,object2) {  
        var a = object[outX]  
        var b = object[outX]  
        //函數代碼  
    }
}
           
  1. 作用域鍊
    1. 本質上是一個指向變量對象的指針清單,它隻引用但不實際包含變量對象。
    2. 在建立A()函數的時候,會建立一個預先包含全局變量的作用域鍊,這個作用域鍊被包含在内部的[[Scope]]屬性中。當調用A()函數時,會為函數建立一個執行環境,然後通過啊複制函數的[[Scope]]屬性中的對象建構起執行環境中的作用域鍊。
    3. 函數執行完後,局部活動對象就會被銷毀,記憶體中僅儲存全局作用域(全局執行環境的變量對象)。
    4. !!!閉包與此不同!!!另一個函數内部定義的函數回京包含函數(即外部函數)的活動對象添加到他的作用域鍊中。換而言之,匿名函數可以通路在out()中定義的所有變量。
  2. 副作用

    閉包隻能取得包含函數中任何變量的最後一個值

    function A() {  
        var result = new Array();  
        for(var i = 0;i < 10;i++) {  
            result[i] = function(){  
                return i;  
            };  
        }  
    } 
               
    //解決
    function A() {  
        var result = new Array();  
        for(var i = 0;i < 10;i++) {  
            result[i] = function(num){  
                return function() {  
                    return num;  
                }
            };  
        }  
    }
               
  3. this對象

    匿名函數的執行環境具有全局性,是以其this對象通常指向window。

  4. 記憶體洩漏

    閉包的作用鍊中包含html元素

模仿塊級作用域

  1. JS沒有塊級作用域的概念。JS不會告訴你是否多次聲明了同一個變量,他會對後續的聲明視而不見但會執行初始化。
  2. 這種技術經常在全局作用域中被用在函數外部,進而限制向全局作用域中的所有變量。
    function A(count) {
        for(var i = 0;i < count;i++) {
            alert(i);
        }
        alert(i);
    }
               
  3. 實作
    (function() {
        //這裡是塊級作用域
    })();
    
    var A = function () {
        //這裡是塊級作用域
    }
    A();
               

私有變量

  • JS中沒有私有成員的概念,所有對象屬性都是共有的。
  • 私有變量:定義在函數中的變量。
  • 特權方法:有權通路私有變量和私有函數的公有方法。
  1. 靜态私有變量

    在一個私有作用域下,定義私有變量或函數。

  2. 子產品模式
    1. 為隻有一個執行個體的對象建立私有變量和特權方法
    2. 如果必須建立一個對象并以某些資料對其進行分初始化,同時還要公開一些能夠通路這些私有資料的方法,那就可以使用子產品模式。
      var A = {
          name : value,
          method : function () {
              //這裡是方法的代碼
          }
      }
                 
  3. 增強的子產品模式

    在傳回對象之前加入對其增強的代碼。比如,能夠通路私有變量的公有方法。

繼續閱讀