為了減少所寫JS代碼對全局環境的污染, 可以采用對象寫法來實現命名空間技術,
以使得局部變量和函數都在對象中作為屬性存在,它們組成某個主題(對象名稱體現)的相關屬性和方法的集合。
如下例:
var MyLib = {}; // global Object cointainer MyLib.value = 1; MyLib.increment = function() { MyLib.value++; } MyLib.show = function() { alert(MyLib.value); } MyLib.value=6; MyLib.increment(); MyLib.show(); // alerts 7
對象定義中每個屬性的定義相對對象松散,優化下:
var MyLib = { value:1, increment:function() {this.value++; }, show: function() { alert(this.value); } };
如何給已有對象添加屬性和方法?
優化后的代碼是類庫的一般寫法,直接修改不是合適的,庫的內容也不容易修改,修改了也不符合開閉法則;
使用優化前的方法 MyLib.xxx = yyy 來實現,可以滿足單實例對象, 但是對於多個實例情況,並且多個屬性和方法需要添加,
每個實例的待添加的屬性和方法又是一致的,方法定義為公共函數, 每個實例都設置一遍所需的屬性和方法,着實顯得笨重。
查閱 apply 和 call 的用法(http://sjolzy.cn/Understanding-JavaScript-in-argumentscalleecallerapply.html),
可以構造一個屬性和方法定義函數, 屬性和方法的前綴為this., 然后使用call將this綁定到具體對象上,就實現了對象擴展。
function base() { this.member =" dnnsun_Member"; this.method =function() { window.alert(this.value); } }
var extObj = { value: 2 } base.call(extObj); extObj.method(); // alert 2
不僅僅對於普通的對象生效, 對於DOM對象也是生效的, 且對於已經綁定過的DOM對象,其克隆仍然具備擴展的特性。
下面給出完整測試代碼:
<html> <head> </head> <body> <input id="button" type="button" value="I am a button"/> <script type='text/javascript'> // 待擴展函數 function base() { this.member =" dnnsun_Member"; this.method =function() { window.alert(this.value); } } /************ Plain OBJECT *******************/ var extObj = { value: 2 } base.call(extObj); extObj.method(); /************ Plain OBJECT *******************/ /************ DOM OBJECT *******************/ base.call(document.getElementById("button")); document.getElementById("button").method() var node = document.getElementById("button").cloneNode(true); document.getElementsByTagName("body")[0].appendChild(node); document.getElementById("button").value += "(clone)"; document.getElementById("button").method(); /************ DOM OBJECT *******************/ </script> </body> </html>