前言
介紹屬性列舉的特徵以及原型的關係
自訂屬性以及原生屬性 不同之處
我們先撰寫了 Person 的建構函式,並且在這個建構函式的原型上給予 name 的屬性,對應到的值是 人類。
再來我們宣告 casper 這個變數為 Person 的實體(instance),同時給予 casper 屬性 a ,對應的值是
undefined 。
function Person () { }
Person.prototype.name = '人類';
var casper = new Person();
casper.a = undefined;
console.log(casper);
先來看看 casper 會印出什麼:
可以看到 a 屬性在 Person 之下,同時 name 屬性在 __proto__ 之下,同時這兩個的屬性顏色都跟其他屬性的方法不一樣,
同為較深的紫色。
我們先加入下列的程式碼來看不同的結果
console.log(casper.hasOwnProperty('a')); // true
console.log(casper.hasOwnProperty('b')); // false
console.log(casper.hasOwnProperty('name')); // false
我們利用 hasOwnProperty 這個方法來查看,該物件是否有我們所要找的屬性。
結果分別是:
- 有
a屬性,當然,我們剛剛有加。 - 沒有
b屬性,因為從頭到尾都沒有。 - 沒有
name屬性,因為name並不屬於casper這個物件的,但是如果要用casper.name的話,還是取的到值。
hasOwnProperty 這個方法就只能找當下的物件屬性,不屬於該物件的屬性的話就會回傳 false 。
接下來我們用列舉的方式看看,會列出那些屬性。
for (var key in casper) {
console.log(key);
}
列舉出來的有 a 屬性,但連 name 也有是為什麼呢?
我們來看看這兩個屬性的特徵:
console.log(Object.getOwnPropertyDescriptor(casper, 'a'));
console.log(Object.getOwnPropertyDescriptor(casper.__proto__, 'name'));
這就跟剛剛的深紫色有關,也就是說深紫色的屬性是我們手動加上去,但其實他屬性的特徵中,enumerable 會顯示為 true。
這個時候,如果我們不想讓 name 的屬性被列舉的話,只要利用 Object.defineProperty 修改就可以了。
function Person () { }
Person.prototype.name = '人類';
Object.defineProperty(Person.prototype, 'name', {
enumerable: false
});
var casper = new Person();
casper.a = undefined;
console.log(casper);
console.log(casper.hasOwnProperty('a'));
console.log(casper.hasOwnProperty('b'));
console.log(casper.hasOwnProperty('name'));
for (var key in casper) {
console.log(key);
}
console.log(Object.getOwnPropertyDescriptor(casper, 'a'));
console.log(Object.getOwnPropertyDescriptor(casper.__proto__, 'name'));
可以發現 name 屬性並沒有出現在列舉的結果中,並且 enumerable 也改成 false 了
以上就是我們自己新增的屬性以及原生的屬性有什麼不同處的介紹
但是有時候我們並不清楚那些屬性是自訂又沒有設定 enumerable 為 false,同時又必須知道哪些是屬於這個物件的屬性的時
候,for in 的迴圈就可以修改成這樣
for (var key in casper) {
if (casper.hasOwnProperty(key)) {
}
}
搭配 hasOwnProperty 的話就可以過濾掉不是屬於該物件的屬性