for in 不能循环动态属性 this.xxx
for in 忽略原型 prototype;
for in 能够循环原型链(__proto__.p1
);
for in 忽略被覆盖的链属性(__proto__.p4&5
)
for in 忽略 enumerable: undefined|null|false|0
总之:忽略动态,忽略原型,忽略被覆盖的链属性及不可枚举的属性this
hasOwnProperty 能够过滤原型链 proto
hasOwnProperty 不能够过滤 enumerable 为真的属性spa
function F() { this.p0 = 'this.p0'; } F.__proto__.p1 = 'f.__proto__.p1'; //链属性没有被覆盖 F.p2 = 'f.p2'; F.prototype.p3 = 'f.prototype.p3'; //原型属性 F.__proto__.p4 = 'f.__proto__.p4'; //链属性被下面的 p4 覆盖 Object.defineProperty(F, 'p4', {value: 'defineProperty enumerable: undefined'}); Object.defineProperty(F, 'p5', {value: 'defineProperty enumerable: true', enumerable: true}); F.__proto__.p5 = 'f.__proto__.p5'; //链属性被上面的 p5 覆盖 for (var k in F) { console.log('hasOwnProperty:', F.hasOwnProperty(k), '\t', k, '->', F[k]); }