js原型連接(二)和object類的create方法

原型鏈的內部執行方式數組

<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的屬性頁沒法更改,這是實際上是沒法進行任何更改的.

相關文章
相關標籤/搜索