#JavaScript學習#第七章:函數表達式

第七章:函數表達式

Tips: 內容爲知識梳理javascript


目錄

  1. 遞歸java

  2. 閉包數組

  3. 模仿塊級做用域bash

  4. 私有變量閉包


定義函數有兩種方式:函數

  1. 函數聲明
function name(arg0,arg1,arg2){
	//代碼
}
複製代碼
  • 函數名.name能夠訪問函數名
  • 函數聲明會被提高,前幾章講過,即執行其餘代碼前會先讀取函數聲明
  1. 函數表達式
    var name =function(arg0,arg1,arg2){
    	//代碼
    };
    複製代碼
  • 這樣建立的函數是匿名函數即沒有名字
  • 這個不會被提高
  • 能夠將函數做爲值返回

1. 遞歸

  • 和java跟c語言遞歸沒啥區別。。。
  • 用arguments.callee可替代當前函數,這是一個指向正在執行函數的指針,用於確保不管怎樣調用函數都不會出問題
  • 嚴格模式下不能使用arguments.callee
  • 嚴格模式下,用命名函數表達式來達到相同效果
var factorial = (function f(num){    
 if (num <= 1){        
   return 1;     
   } else {       
     return num * f(num-1);    
      }
  });
複製代碼

上面函數名爲f,賦值給了factorial。ui

2. 閉包

  • 閉包定義:指有權訪問另外一個函數做用域中變量的函數
  • 其餘的都是關於做用域鏈的內容,沒什麼好講的(以前講過)
  • 過分使用閉包會致使內存佔用過多
  1. 閉包與變量
  • 閉包只能取得包含函數變量的最後一個值
    function ceee(){
    	var sum=new Array();
    	for(i=0;i<10;i++){
    		sum[i]=function(){
    			return i;
    		};
    	}
    	retuen sum;
    }
    複製代碼
    此函數返回的數組都是10,由於閉包做用域鏈保存着包含函數的活動對象,它們引用的都是同一個i,當包含函數返回後,i等於10,因此數組都爲10
  1. 關於this對象
  • 匿名函數的執行環境具備全局性,它的this一般指向window,好比:
    var name="abc";
    var ob=function(){
    	name:"fff",
    	getname:function(){
    		return function(){
    			return this.name;	
    		};
    	}
    };
    複製代碼
    上面代碼的this指向window,由於對於最裏面的函數的做用域鏈,它在搜索this時,逐層往上搜索,由於本身的活動對象中存在this,而這個this是指向全局的,因此不會再往上搜索包含函數的this(不知道這樣說你理解沒有,反正我是理解了),修改方法是把this先保存在一個變量中,再在閉包調用這個變量,此時的this就是指向包含函數
  1. 內存泄露
  • 若閉包中包含一個HTML元素,那麼該元素就沒法被銷燬
  • 把變量設置爲null就能夠解除引用,確保正常回收內存

3. 模仿塊級做用域

javascript無塊級做用域概念,即在塊語句中定義的變量其實也是存在於包含他的外部函數的做用域鏈中,而不是像java和c語言同樣在塊語句結束後就被銷燬。this

  • javascript用匿名函數來模仿塊級做用域,語法以下:
    (function(){
    	//這裏是塊級做用域
    })();
    複製代碼
    匿名函數即函數表達式後面能夠跟圓括號表示當即調用,而函數聲明即有名函數後面不能夠跟圓括號
  • 這樣,在塊級做用域內就能夠擁有本身的私有變量而不怕與外部變量名字衝突

4. 私有變量

  • 在函數內定義的變量都是私有變量外部不能直接訪問
  • 在函數內有權訪問函數的私有變量和私有函數的方法叫特權方法
  • 有兩種模式去定義特權方法
  • 第一種是在構造模式中定義特權方法
    function mobj(){
    	var num=1;//私有變量
    	this.meth = function(){
    		return num;
    	};//特權方法
    }
    複製代碼
    這樣就能夠在外部經過訪問meth這個函數屬性來訪問私有變量
  • 不過使用構造函數模式的缺點是每一個實例都會建立一樣一組新方法,前面講過,用靜態私有變量解決這個問題

1. 靜態私有變量

用原型模式和匿名函數將私有變量變爲全部實例共享,具體以下spa

(function (){
   	var name="abd";//私有變量
   	mbu = function(){};
   	mbu.prototype.publicmetho =function(){
   		return name;
   	};//在原型對象中設置屬性
   })();
複製代碼

上面代碼首先是建立一個私有做用域,而後定義一個私有變量,再不使用var定義一個全局變量mbu,再對mbu的原型對象添加屬性publicmethoprototype

  • 這樣就能夠經過訪問全局變量來訪問私有變量
  • 不過因爲是在原型對象中定義,因此全部實例對這個變量進行操做都會反映到其餘實例上

2. 模塊模式

爲單例建立私有變量和特權方法,語法以下:

var single = function(){
		var pria =20;//私有變量
		return {
			publicee :10;
			publicmetho: function(){
				return pria;
			}//返回一個以字面量建立的對象
		};
	}();
複製代碼

上面代碼返回了一個以字面量建立的對象,這個對象能夠訪問私有變量

  • 這種模式在須要對單例進行初始化,同時又須要維護其私有變量時是很是有用的,這時就能夠用模塊模式

3. 加強的模塊模式

加強模塊模式即在返回對象前加入對其加強的代碼,這種模式適合那些單例必須是某種類型的實例,同時還必須添加某些屬性或方法對其加強的狀況。

相關文章
相關標籤/搜索