1. 程式人生 > >js中的懶載入函式

js中的懶載入函式

測試程式碼1:

function createXHR()
{
	   if(typeof XMLHttpRequest!='undfined')
		{
			return new XMLHttpRequest();
		}else if(typeof ActiveXObject!='undefined')
			{
				//第一次執行的時候不是string,那麼就會執行if裡面的程式碼
				if(typeof arguments.callee.activeXString!='string')
					{
						var versions=['MSXML2.XMLHttp','MSXML2.XMLHttp.3.0','MSXML2.XMLHttp.6.0'];
						for(var i=0,length=versions.length;i<length;i++)
							{
								try{
									var xhr=new ActiveXObject(versions[i]);
									arguments.callee.activeXString=versions[i];
									break;
								}catch(e)
									{	
									}
							}
					}
				//第二次來的時候直接建構函式!因為arguments.callee表示函式createXHR,通過給這個函式附加
				//屬性的方法來進行判斷這個函式是否已經執行過了!
				return new ActiveXOject(arguments.callee.activeXString);
			}else
				{
					throw new Error("不支援XHR");
				}
}
alert(createXHR());//列印XHR物件
alert(createXHR.activeXString);//如果在不執行原生的XHR的瀏覽器中,這裡就會打印出通過IE建立的HXR的版本號,這個屬性是在函式上面!
note:這種構造的問題是,當下次還是在同一個瀏覽器中呼叫該方法,他還是會執行其中的if和else if語句,其實這是完全沒有必要的,因為如果該瀏覽器支援那麼它就一直支援了!所以我們的做法就是在第一次執行後把這個函式賦值為一個新的函式,那麼下次呼叫的時候就呼叫這個新的函式而不用再次進行判斷了!
測試程式碼2:(避免走過多的分支判斷而把函式覆蓋為一個新的函式)
function createXHR()
{
	if(typeof XMLHttpRequest!='undfined')
		{
			createXHR=function()
			{
				return new XMLHttpRequest();
			}	
		}else if(typeof ActiveXObject!='undefined')
			{
				createXHR=function()
				{
				//第一次執行的時候不是string,那麼就會執行if裡面的程式碼
					if(typeof arguments.callee.activeXString!='string')
						{
							var versions=['MSXML2.XMLHttp','MSXML2.XMLHttp.3.0','MSXML2.XMLHttp.6.0'];
							for(var i=0,length=versions.length;i<length;i++)
								{
									try{
										var xhr=new ActiveXObject(versions[i]);
										arguments.callee.activeXString=versions[i];
										break;
									}catch(e)
										{

										}
								}
						}
				//第二次來的時候直接建構函式!因為arguments.callee表示函式createXHR,通過給這個函式附加
				//屬性的方法來進行判斷這個函式是否已經執行過了!
					return new ActiveXOject(arguments.callee.activeXString);
				}
			}else
				{
					createXHR=function()
					{
							throw new Error("不支援XHR");
					}
				}
	//這種通過把函式賦值為一個新的函式的形式還是有效能損失的,因為第一次呼叫的時候返回值會一直等到最後
	//也就是所有的分支都結束的時候,但是以後呼叫會更快!
	return new createXHR();
}
createXHR();
createXHR();
note:這種實現在第一次呼叫的時候存在懲罰,例如瀏覽器支援原生的XHR,那麼返回該物件也會等到程式碼的最後!
測試程式碼3:(通過自執行函式來減少分支判斷)
var createXHR=(function()
{
	if(typeof XMLHttpRequest!='undfined')
		{
			alert(1);
			return function()
			{
				alert(2);
				return new XMLHttpRequest();
			}	
		}else if(typeof ActiveXObject!='undefined')
			{
				return function()
				{
				//第一次執行的時候不是string,那麼就會執行if裡面的程式碼
					if(typeof arguments.callee.activeXString!='string')
						{
							var versions=['MSXML2.XMLHttp','MSXML2.XMLHttp.3.0','MSXML2.XMLHttp.6.0'];
							for(var i=0,length=versions.length;i<length;i++)
								{
									try{
										var xhr=new ActiveXObject(versions[i]);
										arguments.callee.activeXString=versions[i];
										break;
									}catch(e)
										{

										}
								}
						}
				//第二次來的時候直接建構函式!因為arguments.callee表示函式createXHR,通過給這個函式附加
				//屬性的方法來進行判斷這個函式是否已經執行過了!
					return new ActiveXOject(arguments.callee.activeXString);
				}
			}else
				{
					return function()
					{
							throw new Error("不支援XHR");
					}
				}
})();
//這是通過一種自執行的匿名函式來完成的!通過自執行得到函式進而減少多次執行而導致的多餘的if.else判斷
//如果瀏覽器支援原生的XHR那麼你會發現上面只會彈出一次1,其它都是2!
createXHR();
createXHR();
createXHR();
createXHR();
總結:

(1)通過"動態覆蓋"或者"匿名函式自執行"的方式能夠減少每次多餘的分支判斷!

(2)至於圖片懶載入的原理可以閱讀其它的相關知識.