这篇文章会结合属性列举的特徵以及原型的关係做介绍
function Person () { }Person.prototype.name = '人类';var casper = new Person();casper.a = undefined;console.log(casper);
首先先来看看上面的程式码~
我们先撰写了 Person 的建构函式,并且在这个建构函式的原型上给予 name 的属性对应到的值是 人类。
再来我们宣告 casper 这个变数为 Person 的实体(instance),同时给予 casper a 的属性,对应的是 undefined 的值。
这时候我们来看看 casper 会印出甚么。
可以看到 a 属性在 Person 之下,同时 name 属性在 __proto__
之下,同时这两个的属性颜色都跟其他属性的方法不一样,同为较深的紫色。
我们先加入下列的程式码来看看不同的结果~
console.log(casper.hasOwnProperty('a'));console.log(casper.hasOwnProperty('b'));console.log(casper.hasOwnProperty('name'));
我们利用 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
的话就可以过滤掉不是属于该物件的属性噜!
如果没有问题的话就继续往下一篇文章迈进吧! 汪汪~