js中几种遍历对象的方法,包括:
- for in
- Object.keys、Object.values()、Object.entries()
- Object.getOwnPropertyNames()
- for of
- Reflect.ownKeys()它们在使用场景方面各有不同。
1. for in
- 主要用于遍历对象的可枚举属性,包括自有属性、继承自原型的属性。
var obj = {"name":"Poly", "career":"it"}
Object.defineProperty(obj, "age", {value:"forever 18", enumerable:false});
Object.prototype.protoPer1 = function(){console.log("proto");};
Object.prototype.protoPer2 = 2;
console.log("For In : ");
for(var a in obj) console.log(a);
输出如下:
2. Object.keys
返回一个数组,元素均为对象自有的可枚举属性
var obj = {"name":"Poly", "career":"it"}
Object.defineProperty(obj, "age", {value:"forever 18", enumerable:false});
Object.prototype.protoPer1 = function(){console.log("proto");};
Object.prototype.protoPer2 = 2;
console.log("Object.keys:")
console.log(Object.keys(obj));
输出如下:
3. Object.getOwnPropertyNames
用于返回对象的自有属性,包括可枚举和不可枚举的
var obj = {"name":"Poly", "career":"it"}
Object.defineProperty(obj, "age", {value:"forever 18", enumerable:false});
Object.prototype.protoPer1 = function(){console.log("proto");};
Object.prototype.protoPer2 = 2;
console.log("Object.getOwnPropertyNames: ");
console.log(Object.getOwnPropertyNames(obj));
输出如下:
4. Reflect.ownKeys
Reflect.ownKeys可以返回包含symbol作为key的所有键名,包含可枚举和不可枚举的,不包含继承自原型的。
5. for of
必须是可迭代的。
for…of
Iterable object(可迭代对象)
补充:Object.getOwnPropertySymbols()
Object.getOwnPropertySymbols() 方法返回一个给定对象自身的所有 Symbol 属性的数组。
var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");
obj[a] = "localSymbol";
obj[b] = "globalSymbol";
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols.length); // 2
console.log(objectSymbols) // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]) // Symbol(a)
遍历一个对象的自身属性
function toObject(iterator, callback = x => x) {
// 传入一个callback,也就是给toObject暴露一个接口来改变内部的值,默认为 x=>x
const result = {};
for (const item of iterator) {
// item为yield的结果
const [key, value = item] = [].concat(callback(item));
// concat()一个基础数据类型或者一个数组,都返回一个数组
result[key] = value;
}
return result;
}
function hasOwnProperty(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
}
function* iterate(object, symbol = false) {
for (const key in object) {
if (hasOwnProperty(object, key)) {
yield [object[key], key];
}
}
if (symbol) {
for (const key of Object.getOwnPropertySymbols(object)) {
yield [object[key], key];
}
}
}
const obj = {
name: 'xiaoming',
age: '30',
[Symbol(1)]: 11
}
// 封装这部分代码,封装成toObject
// for (let i of iterate(obj, true)) {
// console.log('i', i);
// }
// console.log('res', [...iterate(obj)])
// toObject()
const res = toObject(iterate(obj), x => {
console.log('x', x)
return [x[1], x[0]];
});
console.log('res2', res);