對於本篇對於如何自定義對象、和對象相關的屬性操作不瞭解的話,可以查我對這兩篇博客。瞭解後可以更容易理解本篇文章 用構造函數創建了一個對象 obj對象的本身創建了兩個屬性 x=1 ,y=2 對象本的的兩個屬性都有屬性特征 writable是否可寫的,enumerable是否可枚舉的 configura
對於本篇對於如何自定義對象、和對象相關的屬性操作不瞭解的話,可以查我對這兩篇博客。瞭解後可以更容易理解本篇文章
用構造函數創建了一個對象
obj對象的本身創建了兩個屬性 x=1 ,y=2
對象本的的兩個屬性都有屬性特征 writable是否可寫的,enumerable是否可枚舉的 configurable是否可重置的,getter ,setter
obj對象本身也有三大特性 proto 原型 class 類 extensible可拓展
foo.prototype是對象上的原型 , foo.prototype也是個對象。
z=3是foo.prototype是對象上原型的屬性。
再往上object.prototype是一個頂級屬性,是所有對象的原型。
再上往上就是null 空了。 此時就形成了一個原型鏈。
我再用代碼來一一解析,用演示代碼再向大家詳細解釋:
1 <script> 2 function Foo(){ //聲名一個函數FOO 3 4 } 5 alert(typeof Foo.prototype) //Foo.prototype 是一個對象。也可以是obj對象上的原型 6 Foo.prototype.z =3 //設置了原型屬性z為3 7 var obj = new Foo() //用構建函數來創建了obj對象 8 obj.x = 1; //x=1是obj對象上本身的屬性 9 obj.y = 2; //y=2是obj對象上本身的屬性 10 alert(obj.x) //=>1 對過查詢對象,我們是否得到這個屬性值 11 alert(obj.y) //=>1 對過查詢對象,我們是否得到這個屬性值 12 alert(obj.z) //=》3 z不是obj本身的屬性,是他原型上的屬性,如果本身沒有,可以向他的原型鏈上的原型來查找,得到z屬性 13 alert(obj.toString())//=toString是頂級object對象上的屬性,先是查找原型上有沒有這個屬性,如果沒有再往原型鏈上頂級的object對象上找 14 </script>
再來瞭解一下得到對象上屬性的優先順序。
如果在對象本身上有這個屬性,則得到的是對象上本身的屬性。
如果對象本身上沿岸有這個屬性,則向他的原型上查找。
如果再沒有再向頂級屬性上查找。
如果原型上和對象本身上都有這個屬性,則還是先用對象本身的屬性
為了讓大家更好的瞭解,演示代碼如下:
1 <script> 2 function Foo(){ //聲名一個函數FOO 3 4 } 5 Foo.prototype.z =3 //設置了原型屬性z為3 6 var obj = new Foo() //用構建函數來創建了obj對象 7 obj.z = 5 //定義對象的屬性Z = 5 8 alert(obj.z) //=>5 如果對象上本身定義了屬性z ,則先用對象本身的屬性 9 delete obj.z; //刪除對象上本身的屬性 10 alert(obj.z); //=>3再次獲取對象的z,結果發現對象本身z的屬性被刪除了,會自動往對象的原型上查找,得到z=3 11 delete Foo.prototype.z; //刪除對象原型上的z屬性 12 alert(obj.z) //=> undefined 因為對象本身的z屬性被刪除,原型上的z屬性也被刪除,再繼續往頂級對象Object上查找,沒有此屬性,返回undefined 13 </script>
通過 var obj = Object.create({x:1}) 來創建對象來解析對象、對象上的原型
其實obj.create圓括弧裡面定義對象和屬性就是obj對象的原型和原型屬性,
演示代碼如下:
1 <script> 2 var obj = Object.create({z:4}) //Object.create({z:4})是一個對象上的一個原型,z是原型上的屬性 3 obj.x = 1 //x是對象本身的屬性 4 obj.z = 3 //z是對象本身的屬性 5 alert(obj.x) //=>1 輸出的是對象本身的x 6 alert(obj.z) //=>3 輸出的是對象本身的z 7 delete obj.z; //當我們刪除對象本的z 8 alert(obj.z) //就是會向原型上面查找原型上有沒有這個屬性,如果有,z指的是原型上的屬性 9 </script>
通過In來解釋某個對象上是否有這個屬性:
演示代碼如下:
1 <script> 2 //用 屬性 In 對象來檢測 是否是對象上的屬性,返回true否是,返回false 則不是 3 function Foo(){ 4 5 } 6 Foo.prototype.z = 5 7 var obj = new Foo() 8 obj.x = 1 ; 9 obj.y = 2; 10 alert("x" in obj) //=>true x是對象上本身定義的屬性 11 alert("y" in obj) //=>true y也是對象上本身定義的屬性 12 alert("z" in obj) //=>true z是從對象原型上繼承來的屬性 13 alert("toString" in obj) //=>true toString是從頂級對象Object上繼承來的屬性 14 alert("no" in obj) //=>false 對象本上沒有,查找整個原型鏈都沒有這個屬性直到null 則反回false, 15 </script>
通過hasOwnProperty查找是否是對象本身的屬性,而不是繼承來的屬性
1 <script> 2 //用對象.hasOwnProperty("屬性") 來檢測是否是對象本身的屬性,而不是繼承來的 3 function Foo(){ 4 5 } 6 Foo.prototype.z = 5 7 var obj = new Foo() 8 obj.x = 1 ; 9 obj.y = 2; 10 alert(obj.hasOwnProperty("x")) //=>true x是對象本身定義的屬性,所以返回true 11 alert(obj.hasOwnProperty("z")) //=>false z是對象原型上繼承的屬性,所以返回false 12 alert(obj.hasOwnProperty("toString")) //=>false toString是頂級對象上繼承來的屬性,所以返回false 13 </script>
我們最後來看看用var obj = Objcet.create()來創建的對象如何來檢測他的屬性。
如果想沒有任何繼續屬性的話可以寫 var obj = Object.create(null) 則不繼承任何屬性
演示代碼:
1 <script> 2 var obj = Object.create({x:1}) 3 obj.y = 2 4 alert("y" in obj) //=>true 5 alert("x" in obj) //=>true 6 alert("toString" in obj) //=>true 7 alert(obj.hasOwnProperty("x")) //=>false 8 alert(obj.hasOwnProperty("y")) //=>true 9 var obj1 = Object.create(null) 10 alert("toString" in obj1) //=>false 創建了一個不繼承任何屬性的對象obj1,直到頂級對象Object對象都不繼承 11 </script>