原型鏈的內部執行方式數組
<script> function Myclass(){ this.x=" x in Myclass"; } var obj=new Myclass(); p(obj.x); p(obj.z); //undefined Myclass.prototype.z="z in Myclass"; p(obj.z); //首先查找自身屬性,若是沒有找到 將沿着原型連接 查找構造函數(Myclass)的prototype對象裏找 </script>
屬性的重寫與刪除與原型鏈無關ide
<script> function Myclass(){ this.x=" x in Myclass"; } Myclass.prototype.y="y in Myclass"; var obj=new Myclass(); p(obj.y);//y in Myclass obj.y="override y"; p(obj.y);//override y delete obj.y //true p(obj.y);//y in Myclass var obj2=new Myclass(); p(obj2.y);//y in Myclass obj.z='zzz'; p(obj.z);//zzz p(obj2.z);//undefined p(obj.prototype);//undefined </script>
獲取原型對象的三種方法函數
<script> function Myclass(){} var proto=Myclass.prototype; var obj=new Myclass(); //經過第五版裏增強 var proto=Object.getPrototypeOf(obj); //經過對象實例得到 var proto=obj.__proto__; //經過對象實例以及其構造函數 var proto=obj.constructor.prototype; p(obj.constructor==Myclass); //true </script>
經過constructor斷定數據類型this
<script> var d=new Date(); p(d.constructor);//function Date() { [native code] } var arr=[1,2,3]; p(arr.constructor);//function Array() { [native code] } var obj={}; p(obj.constructor);//function Object() { [native code] } </script>
constructor屬性並非對象的直接屬性,而是經過原型連接 查找到的
每一個對象在建立時 構造器會執行這樣一句代碼
this.prototype=
{
constructor:this,
__proto__:Object.prototype
}
經過改變prototype實現繼承spa
<script> function Derived(){} //建立時 就有了Derived.prototype={constructor:Derived} p(Derived.prototype.__proto__==Object.prototype);//true p(Derived.__proto__);//function Empty() {} function Base(){} //原理同上 Derived.prototype=new Base(); //此時Derived.prototype的原型連接__proto__改變了指向 p(Derived.prototype.__proto__==Base.prototype); //true var obj=new Derived(); //此時 p(obj.__proto__==Derived.prototype);//true //如今obj裏找 ,沒有,到Derived.prototype引用的對象Base裏找,沒有,就到Base.prototype裏找了 p(obj.constructor); //function Base(){} </script>
數據類型斷定(instanceof與isPrototypeOf)prototype
<script> var d=new Date(); p(Date.__proto__);////function Empty() {} p(d instanceof Date);//true p(d instanceof Object);//true p(Date instanceof Object);//true p(Object instanceof Date);//false function Derived(){} function Base(){} Derived.prototype=new Base(); var obj=new Derived(); p(obj instanceof Derived);//true p(obj instanceof Base); //true p(Derived instanceof Base);//false Derived不是由 Base構造函數生成的 p(Derived.constructor);//function Function() { [native code] } p(Derived instanceof Object);//true p(Derived.prototype.isPrototypeOf(obj)); //true Base.prototype.isPrototypeOf(obj);//true Object.prototype.isPrototypeOf(obj)//true </script>
屬性的枚舉
in 能夠可判斷自己屬性和經過繼承來的屬性 是否存在於某個對象
hasOwnProperty只列出自己能夠枚舉的屬性
有些屬性被枚舉出來是由於enumerable屬性爲false
getOwnPropertyNames能夠無視枚舉屬性,列舉出全部屬性code
<script> var obj={x:1,y:2}; p(Object.keys(obj));//x,y obj.z=3; //obj.prototype.p='pp';//實例 prototype屬性 p(obj.prototype);//undefined p(obj.__proto__==Object.prototype); //true p(Object.keys(obj));//x,y,x var arr=[1,2,3]; p(Object.keys(arr)); //0,1,2 p(Object.getOwnPropertyNames(arr)); //0,1,2,length p(Object.keys(Object.prototype));//空 p(Object.getOwnPropertyNames(Object.prototype)); /* constructor,toString,toLocaleString,valueOf,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,__defineGetter__,__lookupGetter__,__defineSetter__,__lookupSetter__,__proto__ */ //對於enumerable可根據propertyIsEnumerable來判斷 function Myclass(){ this.x=1;this.y=2; } Myclass.prototype.z=3; var obj=new Myclass(); p(Object.getOwnPropertyNames(obj)); //x,y 不列舉經過繼承獲取的屬性 p(Object.keys(obj));// x,y for(var key in obj){ p(key); } //x,y,z </script>
ECMAScript裏的Object類
Object裏的create方法,是除了對象字面量與new表達式以外的第三種官方的生成對象的方法
第一個參數須要一個原型對象,第二個參數須要一個屬性對象。
若是將一個null做爲原型傳遞給create方法 ,則會生成一個沒有進行原型繼承的對象對象
<script> var obj=Object.create(null); p(Object.getPrototypeOf(obj));//null p("toString" in obj);//false var obj=Object.create(Object.prototype); //與 var obj={}; //等效 p(obj.__proto__===Object.prototype);//true p(obj.constructor==Object);//true function Myclass(){} var Proto={x:2,y:3}; Myclass.prototype=Proto; var obj=new Myclass(); //下面代碼等價 var Proto={x:2,y:3}; var obj=Object.create(Proto); </script>
屬性對象
create方法的第二個參數是一個關聯數組,其鍵爲屬性名,其值爲屬性描述符(屬性對象)
屬性描述符指由下表中的 由屬性組成的關聯數組blog
屬性對象
create方法的第二個參數是一個關聯數組,其鍵爲屬性名,其值爲屬性描述符(屬性對象)
屬性描述符指由下表中的 由屬性組成的關聯數組繼承
屬性的屬性名 |
含義 |
writable |
能夠改寫屬性的值 |
enumerable |
能夠經過for in枚舉出 |
configurable |
能夠改變屬性的屬性,能夠刪除屬性 |
get |
能夠指定屬性值的getter函數 |
set |
能夠指定屬性值的setter函數 |
屬性值經過value屬性指定.大部分屬性的默認值是false,也能夠顯示地指定爲true
<script> var obj={x:2,y:3}; //與下面代碼 var obj=Object.create(Object.prototype, { x:{value:2,writable:true,enumerable:true,configurable:true}, y:{value:2,writable:true,enumerable:true,configurable:true} } ); // 是等效的 </script>
與Object類的屬性的屬性有關的方法
方法 |
說明 |
defineProperty(o,p,attributes) |
向對象o增長/更新具備特定信息的屬性p |
defineProperties(o,properties) |
向對象o增長/更新具備特定信息的屬性 |
getOwnPropertyDescriptior(o,p) |
返回對象o的直接屬性p的信息(值與屬性) |
<script> var obj=Object.create(Object.prototype,{x:{value:2}}); //除了顯式指定的屬性,其它的值都爲false value默認爲undefined Object.getOwnPropertyDescriptor(obj,'x'); //{value:2,writable:false,enumerable:false,configurable:false} //新增屬性y Object.defineProperty(obj,'y',{value:3,enumerable:true}); Object.getOwnPropertyDescriptor(obj,'y'); //{value:3,writable:false,enumerable:true,configurable:false} // 新增屬性z Object.defineProperties(obj, { z:{value:function(){alert('z called');},enumerable:true} } ); Object.getOwnPropertyDescriptor(obj,'z'); //{value:function(){alert('z called');},enumerable:true,configurable:false,writable:false} </script>
若是屬性的configurable屬性爲true,能夠更改包括值在內的全部屬性,反之若是爲false,則不能
因爲此時configurable的屬性頁沒法更改,這是實際上是沒法進行任何更改的.