1. 检测某个成员(属性/键) 是否属于这个对象,或者是否属于这个对象的私有属性
-
in:
检测成员是否属于这个对象「特点:不论是私有属性,还是公有属性,只要有则检测结果就是true」 -
hasOwnProperty:
用来检测当前成员是否为对象的私有属性「特点:只要是私有属性,结果才是true,哪怕有这个属性,但是属于公有的属性,结果也是 false」
function Fn() {
this.x = 10
this.y = 20
}
const f1 = new Fn()
console.log('x' in f1) // true
console.log(f1.hasOwnProperty('x')) // true
console.log('hasOwnProperty' in f1) // true
console.log(f1.hasOwnProperty('hasOwnProperty')) // false 不是它的私有属性,是它的公有属性
复制代码
-
检测这个属性是否是这个对象的公有属性
思路一:
是它的属性,但是还不是私有的,那么一定是公有的。「BUG:
如果某个属性即使私有的,也是公有的,则检测出来的结果是不准确的」。
function hasPubProperty(obj, attr) { return (attr in obj) && (!obj.hasOwnProperty(attr)) } 复制代码
思路二:
真正的思路应该是检测原型上的属性,因为原型上的属性都是公有的。
function hasPubProperty(obj, attr) { // Object.getPrototypeOf 获取当前对象的原型 let proto = Object.getPrototypeOf(obj) while(proto) { // 依次查找原型链,直到找到 Object.prototype 为止 if(proto.hasOwnProperty(attr)) { return true } proto = Object.getPrototypeOf(proto) } return false } 复制代码
2. for in 遍历问题
-
问题1:
- 很多对
对象
的操作时无法拿到 Symbol 属性的
const sy = Symbol() const obj = { name: 'zhufeng', [sy]: 100 } for(let key in obj) { console.log(key) // 无法遍历 Symbol 的私有属性 } 复制代码
解决:
只想遍历私有的,包含 Symbol 的
// Object.keys 获取一个对象非 Symbol 的私有属性 // Object.getOwnPropertySymbols 只获取 Symbol 的私有属性 const keys = [ ...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj) ] keys.forEach(key => { console.log(key, obj[key]) }) 复制代码
- 很多对
-
问题2:
- 可以遍历到自己扩展的公共属性「内置的公共属性是不可枚举的(就是无法遍历到的)」
const obj = { name: 'zhufeng' } obj.prototype.AAA = 100 // AAA 是 obj 的公共属性 for(let key in obj) { console.log(key) // 把公有属性也遍历出来了 } 复制代码
解决:
能够避免遍历公共的
for(let key in obj) { // 已经遍历到公共的,则私有已经遍历完,结束循环 if(!obj.hasOwnProperty(key)) break console.log(key) } 复制代码
-
问题3:
- 优先遍历数字属性,而且按照从小到大(不会严格按照属性书写的顺序)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END