几种遍历一个对象包含的所有属性的方法详解【上】(包括可枚举属性、不可枚举属性以及symbol属性)

前言

对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor()方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

通过字面量方式创建一个对象obj,并获取其自有属性foo的属性描述符。代码如下所示:

let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo');

显示结果如下图所示:
在这里插入图片描述
描述对象Descriptor的enumerable属性,称为“可枚举性”,如果该属性为false,就表示不可枚举,即某些操作会忽略当前属性。

var obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo').enumerable;

显示结果如下图所示:
在这里插入图片描述
在遍历一个对象的属性时,通常根据属性是否可枚举这个标准来进行。目前有四种方法仅对可枚举的属性进行遍历,分别为:

  • for…in;
  • Object.keys();
  • JSON.stringify();
  • Object.assign()【ES6新增】

本文仅介绍可以遍历对象所有属性的方法,也就是对属性的可枚举性和不可枚举性不做限制的两种方法进行介绍。

一、Object.getOwnPropertyNames(obj)【不遍历Symbol属性】

Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。数组中枚举属性的顺序与通过 for…in 循环(或 Object.keys)迭代该对象属性时一致。数组中不可枚举属性的顺序未定义。

案例一

var obj = {
    name: 'aaa',
    age: 'bbb',
    say: 'ccc',
    [Symbol("id")]: 'ddd'  //设置Symbol属性
}
Object.defineProperty(obj, 'say', {  //设置obj对象的say不可枚举
    enumerable: false
});
Object.getOwnPropertyNames(obj).forEach(function(key){
	console.log(key+"\t\t\t\t"+key+".enumerable="+Object.getOwnPropertyDescriptor(obj, key).enumerable+"\t\t\t\t"+'result='+obj[key]);
});

显示结果如下图所示:
在这里插入图片描述
案例二

对Object对象的所有属性进行遍历:

Object.getOwnPropertyNames(Object).forEach(function(key){
	getStrLen(key);
	console.log(key+str+key+".enumerable="+Object.getOwnPropertyDescriptor(Object, key).enumerable+str+'result='+Object[key]);
});
//计算key的长度和应该添加的tab个数
var str = "";//tab字符串
function getStrLen(key){
	let bitNum = 3;//属性字符串每3位输出一个tab键
	let maxLen = 25;//属性字符串的最大长度为25
	let num = Math.ceil(key.length/bitNum);
	let p = Math.ceil(maxLen/bitNum+1);
	str = "";
	for(let i = p; i > num; i--){
		str += "\t";
	}
}

显示结果如下图所示:
在这里插入图片描述
由上图可知:Object对象的所有属性均为不可枚举类型。

二、Reflect.ownKeys(obj)【遍历Symbol属性】

静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。其返回值是由目标对象的自身属性键组成的 Array。 即其返回值等同于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)),也就是说Reflect.ownKeys(obj)的返回值是在Object.getOwnPropertyNames(target)返回值与symbol类型的值之和。

扫描二维码关注公众号,回复: 10650130 查看本文章

案例一

var obj = {
    name: 'aaa',
    age: 'bbb',
    say: 'ccc',
    [Symbol("id")]: 'ddd'  //设置Symbol属性
}
Object.defineProperty(obj, 'say', {  //设置obj对象的say不可枚举
    enumerable: false
});
console.log(Reflect.ownKeys(obj));
Reflect.ownKeys(obj).forEach(function(key){
	if(typeof key == "symbol"){
		console.log("----------------------我是Symbol类型,不参与运算-------------------------");
		console.log(key);
	}else{
		console.log(key+"\t\t\t\t"+key+".enumerable="+Object.getOwnPropertyDescriptor(obj, key).enumerable+"\t\t\t\t"+'result='+obj[key]);
	}
});

显示结果如下图所示:
在这里插入图片描述
案例二

Reflect.ownKeys(Object).forEach(function(key){
	getStrLen(key);
	console.log(parseInt(keyNum)+"、"+key+str+key+".enumerable="+Object.getOwnPropertyDescriptor(Object, key).enumerable+str+'result='+Object[key]);
});
//计算key的长度和应该添加的tab个数
var str = "";//tab字符串
var keyNum = 0;//记忆当前属性的输出次序
function getStrLen(key){
	let bitNum = 3;//属性字符串每3位输出一个tab键
	let maxLen = 25;//属性字符串的最大长度为25
	let num = Math.ceil(key.length/bitNum);
	let p = Math.ceil(maxLen/bitNum+1);
	str = "";
	for(let i = p; i > num; i--){
		str += "\t";
	}
	keyNum++;
}

显示结果如下图所示:
在这里插入图片描述
对于不包含symbol类型属性的对象来说,Reflect.ownKeys(obj)的返回值与Object.getOwnPropertyNames(obj)相同。

好啦,关于JavaScript获取一个对象所有属性(可枚举属性和不可枚举属性)的所有方法都整理在这里啦,希望能帮到各位!若有考虑不周之处,还望指正!

发布了33 篇原创文章 · 获赞 35 · 访问量 811

猜你喜欢

转载自blog.csdn.net/chaopingyao/article/details/105414146