对象属性的遍历(二)

13 篇文章 2 订阅
12 篇文章 3 订阅

在之前的文章中,我们提到过三个遍历对象属性的原生API ——Object.keys()、Object.values()、Object.entries()。

这三个API很常用,但是它们有自己的局限,在上文中提到过,首先它们三者都对“不可遍历”的属性“无可奈何”,其次对于“Symbol”属性,它们同样也无法遍历。所以在这里我们要系统的上述一下对象属性遍历的内容。

刚刚我们提到过,对象的属性有时是不可枚举的,那么什么时候属性不可枚举,为什么要存在这种不可枚举的属性呢?这些问题都牵扯到早起JavaScript的历史。

以JavaScript为首的ECMAScript语言不通与Java等面向对象的语言。在Java语言的设计里,“对象”这一概念是作为“类”的衍生品存在的,在Java中“对象”是“类”的实例化,就像是鸡和蛋的关系一样,没有鸡就没有蛋。但是JavaScript不同,在设计之初,JavaScript是没有类这一概念的。

在早起的web时代,“对象”是“程序员手写的大括号”,小工程一般也就是几十个对象之间的互动罢了,如果工程较大的话,那就写一个函数,在函数(构造函数)中“return 对象”,在对象之间设定原型关系,组成原型链来继承属性和方法(提高复用性)。

之后过去了几年(ES3的时代),web工程的需求和工作量激增,之前的三板斧不好用了,在这个时间段里,如果工程里的对象都是手写的话,程序员早就累死了,没办法,一些高端的web程序员,巧妙地用“构造函数”和“this指针”实现了“类”,用“apply和call”方法实现了“类的继承”,进而实现“接口”、“抽象类”等基础概念和“众多设计模式”。此时前端程序员开始用“类似传统面向对象”的工作方式来开发web程序。

但巧妇难为无米之炊,在应用的层面上实现语言层该有的东西,总是难以尽善尽美,例如,虽然技术高超的web程序员能够实现“类”这一机制,但是无法实现类中“私有成员”这一机制(事实上直到今天ES6里也没有实现这一功能)。程序员们此时大多彼此约定,变量名中以下划线开头的变量,是我代码里的私有便令,你写程序的时候就是看见了它也别用它。

再后来ES5.1的时代到来了。此时正值ES4刚刚宣布开发失败不旧,没有什么强有力的语法更新,class等机制也没有登台,ECMAScript组织就在Object上面增加了一些补丁,其中很重要的一点就是,对象的属性开始有了“特性”这一概念。

所谓“属性的特性”指的是属性的一些性质,例如"可读性"、“可写性”、“可枚举性”和“可继承性”等。此时“class”仍然只是一种开发技巧,在语言的层面上,ECMA仍然认为,ECMAScript是一种基于对象开发的语言,所以,ECMA就说,如果对于一个对象来说,我有属性A,但是你不可以枚举它,不可以write它,甚至你不能read它,那它和“私有”的又有什么区别呢?

故此,在ECMAScript5.1版本中,增加了一些设置属性特性的API,对象的属性有些变得不可枚举。进而造成了之前我们说的遍历对象属性时的那些问题。

那么总结一下,属性遍历的方法有几种呢?——五种:

  1. 利用for...in循环遍历属性;——循环对象自身的属性,对象继承来的属性,不会遍历不可枚举的属性,不会遍历Symbol属性。
  2. 利用Object.keys(obj)、Object.values(Obj)、Object.entries(Obj)遍历属性;——详见上一篇文章
  3. 利用Object.getOwnPropertyName(Obj)遍历属性;——返回一个数组,返回对象自身所有的除了Symbol属性之外的所有属性(包括不可枚举的属性)的键名。
  4. 利用Object.getOwnPropertySymbols(Obj)遍历属性;——返回一个数组,包含对象自身所有Symbol属性键名。
  5. 利用Relect.ownKeys(obj)遍历属性;返回一个数组,包含对象自身所有属性,无论键名是否是Symbol,也不管属性是否可枚举。
以上的5中方法,在遍历对象键名的时候,都遵循同样的遍历次序,规则如下:
首先遍历所有数值键,按照从小到大的顺序排列
其次遍历所以字符串键,按照加入时间顺序,升序排列。
最后遍历所有Symbol键,按照时间顺序,升序排列。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值