<script> function p(){ var len=arguments.length; for(var i=0;i<len;i++){ document.write(arguments[i]+"<br/>"); } } function Myclass(x,y){ this.x=x; this.y=y; this.show=function(){ return this.x+this.y; } } var m1=new Myclass(1,2); var m2=new Myclass(3,4); p(m1.show(),m2.show()); </script>
存在的問題
1.由於所有的實例都是復制了同一個方法所定義的實體,所以效率(內存效率與執行效率低下),可通過原型繼承解決
2.無法對屬性值進行訪問控制(private ,Public)可通過閉包解決
屬性訪問的運算對象不是變量而是對象的引用
僅讀取數值的整數部分的處理
Math[this<0?'celling':'floor'](this);
關聯數組
在js中必須通過對象才能實現關聯數組
基本操作 通過鍵取值,元素的設定,元素的刪除
<script> var map={x:3,y:4}; p(map.x); delete map.x; //true p(map.x); //undefined 對不存在的元素進行訪問結果是undefined ,由於可以顯示地將值設置為undefined ,因此無法通過將值與undefined比較來判斷值是否存在 ,可以通過for in進行枚舉 a='undefined'; p(a);//undefined p(typeof map.x==a); //true </script>
作為關聯數組應該注意的點
<script> function Myclass(x,y){ this.x=x; this.y=y; } Myclass.prototype.z=5; var obj=new Myclass(1,2); for(var key in obj){ p(key+":"+obj[key]); //會枚舉出通過原型繼承來的屬性 } //x:1 y:2 z:5 delete obj.x;//true p(obj.x); //undefined p(obj.z); //5 //通過原型繼承來的屬性 無法被delete刪除 delete obj.z; //true p(obj.z);//5 //在將對象作為關聯數組使用時,通常都會使用字面量來創建,即使視圖通過使用空的對象字面量來創建一個沒有元素的關聯數組,也仍會從Object類中繼承原型的屬性 p('toString' in obj); //true var obj1={}; p('toString' in obj1);//true //通過 for in枚舉 p(obj1.length); //undefined for(var k in obj1){ p(obj1[k]); } //沒有元素 被枚舉出來 這是由於enumerable屬性的緣故 //通過hasOwnProperty來判斷 是本身的屬性還是通過 參與原型繼承而來的屬性 var map={}; p(map.hasOwnProperty('toString')); //false map['toString']=1; p(map.hasOwnProperty('toString')); //true delete map['toString'] ; p(map.hasOwnProperty('toString'));//false </script>
屬性的屬性
對象的屬性 也是有些屬性的
如下表總結了在ECMAScript第五版定義了的屬性 ,屬性值被定為為值屬性
表格1
屬性的屬性名
含義
writable
可以改寫屬性的值
enumerable
可以通過for in枚舉出
configurable
可以改變屬性的屬性,可以刪除屬性
get
可以指定屬性值的getter函數
set
可以指定屬性值的setter函數
不可變對象
即生成之後狀態不能再被改變的對象,字符串對象就是典型的不可變對象
靈活運用不可變對象可以提高程序的健壯性,比如在將傳遞給方法參數時,存在方法對對象內容的改寫等
js中可通過以下方式實現不可變對象
1.將屬性(狀態隱藏藏) ,不提供變更操作(閉包實現)
2.靈活運用ECMAScript第五版提供的函數
3.靈活運用writable,configurable屬性以及setter和getter
ECMAScript第五版中用於支持對象不可變的函數 見下表格
方法名
屬性新增
屬性刪除
屬性值變更
確認方法
preventExtensions
x
o
o
Object.isExtensible
seal
x
x
o
Object.isSealed
freeze
x
x
x
Object.isFrozen
Object.preventExtensions例子
<script> var obj={x:2,y:3}; Object.preventExtensions(obj); //無法新增屬性 obj.z=4; p(Object.keys(obj));//x,y //可以刪除屬性 delete obj.y; p(Object.keys(obj)); //x //可以更改屬性值 obj.x=20; p(obj.x); //20 //Object.seal例子 將屬性的configurable設置為假 var obj={x:2,y:3}; Object.seal(obj); //無法新增 也無法刪除 obj.z=3; p(Object.keys(obj)); //x,y delete obj.x; //false p(Object.keys(obj));//x,y //可以改變 屬性值 obj.x=20; p(obj.x);//20 //Object.freeze例子 將屬性的writable設置為假 var obj={x:2,y:3}; Object.freeze(obj); //無法新增 也無法刪除,也無法改變屬性值 obj.z=3; p(Object.keys(obj)); //x,y delete obj.x; p(Object.keys(obj));//x,y //可以改變 屬性值 obj.x=20; p(obj.x);//20 </script>
需要注意
1.對於以上三種方法一旦更改就無法還原
2.如果想讓原型繼承中的被繼承的方法也不可改變,需要對其進行顯示操作