<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; //truep(map.x); //undefined 對不存在的元素進行訪問結果是undefined ,由于可以顯示地將值設置為undefined ,因此無法通過將值與undefined比較來判斷值是否存在 ,可以通過for in進行枚舉a='undefined';p(a);//undefinedp(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:5delete obj.x;//truep(obj.x); //undefinedp(obj.z); //5//通過原型繼承來的屬性 無法被delete刪除delete obj.z; //truep(obj.z);//5//在將對象作為關聯數組使用時,通常都會使用字面量來創建,即使視圖通過使用空的對象字面量來創建一個沒有元素的關聯數組,也仍會從Object類中繼承原型的屬性p('toString' in obj); //truevar obj1={};p('toString' in obj1);//true//通過 for in枚舉p(obj1.length); //undefinedfor(var k in obj1){ p(obj1[k]);}//沒有元素 被枚舉出來 這是由于enumerable屬性的緣故//通過hasOwnProperty來判斷 是本身的屬性還是通過 參與原型繼承而來的屬性var map={};p(map.hasOwnProperty('toString')); //falsemap['toString']=1;p(map.hasOwnProperty('toString')); //truedelete 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,ydelete obj.x; //falsep(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,ydelete obj.x;p(Object.keys(obj));//x,y//可以改變 屬性值obj.x=20;p(obj.x);//20</script>
需要注意
1.對于以上三種方法一旦更改就無法還原
2.如果想讓原型繼承中的被繼承的方法也不可改變,需要對其進行顯示操作
新聞熱點
疑難解答