JavaScript單例模式
阿新 • • 發佈:2019-01-29
全域性變數不是單例模式,但在JavaScript 開發中,我們經常會把全域性變數當成單例來使用。
使用名稱空間可以減少全域性變數的數量,以下程式碼是動態建立名稱空間:
var MyApp = {};
MyApp.namespace = function( name ){
var parts = name.split( '.' );
var current = MyApp;
for ( var i in parts ){
if ( !current[ parts[ i ] ] ){
current[ parts[ i ] ] = {};
}
current = current[ parts[ i ] ];
}
};
MyApp.namespace( 'event' );
MyApp.namespace( 'dom.style' );
console.dir( MyApp );
// 上述程式碼等價於:
var MyApp = {
event: {},
dom: {
style: {}
}
};
使用閉包封裝私有變數
這種方法把一些變數封裝在閉包的內部,只暴露一些介面跟外界通訊:
var user = (function(){
var __name = 'sven',
__age = 29;
return {
getUserInfo: function(){
return __name + '-' + __age;
}
}
})();
此處user物件包含多個函式,可以當成名稱空間來用。
通用的惰性單例:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<button id="loginBtn">登入</button>
</body>
<script>
var getSingle = function(fn) {
var result;
return function() {
return result || (result = fn.apply(this, arguments));
}
};
var createLoginLayer = function() {
var div = document.createElement('div');
div.innerHTML = '我是登入浮窗';
div.style.display = 'none';
document.body.appendChild(div);
return div;
};
var createSingleLoginLayer = getSingle(createLoginLayer);
document.getElementById('loginBtn').onclick = function() {
var loginLayer = createSingleLoginLayer();
loginLayer.style.display = 'block';
};
//下面我們再試試建立唯一的iframe 用於動態載入第三方頁面:
/*var createSingleIframe = getSingle( function(){
var iframe = document.createElement ( 'iframe' );
document.body.appendChild( iframe );
return iframe;
});
document.getElementById( 'loginBtn' ).onclick = function(){
var loginLayer = createSingleIframe();
loginLayer.src = 'http://baidu.com';
};*/
</script>
</html>
這種單例模式的用途遠不止建立物件,比如我們通常渲染完頁面中的一個列表之後,接下來要給這個列表繫結click 事件,如果是通過ajax 動態往列表裡追加資料,在使用事件代理的前提下,click 事件實際上只需要在第一次渲染列表的時候被繫結一次,但是我們不想去判斷當前是否是第一次渲染列表,如果藉助於jQuery,我們通常選擇給節點繫結one 事件:
var bindEvent = function(){ $( 'div' ).one( 'click', function(){ alert ( 'click' ); }); }; var render = function(){ console.log( '開始渲染列表' ); bindEvent(); }; render(); render(); render(); var bindEvent = getSingle(function(){ document.getElementById( 'div1' ).onclick = function(){ alert ( 'click' ); } return true; }); var render = function(){ console.log( '開始渲染列表' ); bindEvent(); }; render(); render(); render();
總結:也就是說只要是想要哪個程式碼塊只執行一次就可以用這個惰性的getSingle函式。