JS中轻松遍历对象属性的几种方式小白知识_属性新手入门

自身可枚举属性Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for…in循环遍历该对象时返回的顺序一致 。如果对象的键-值都不可枚举,那么将返回由键组成的数组。这是合理的,因为大多数时候只需要关注对象自身的属性。来看看一个对象拥有自身和继承属性的例子,Object.keys()只返回自己

JS中轻松遍历对象属性的几种方式小白知识

自身可枚举属性

Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for…in循环遍历该对象时返回的顺序一致 。如果对象的键-值都不可枚举,那么将返回由键组成的数组。

JS中轻松遍历对象属性的几种方式小白知识_属性新手入门

这是合理的,因为大多数时候只需要关注对象自身的属性。

来看看一个对象拥有自身和继承属性的例子,Object.keys()只返回自己的属性键:

let simpleColors = {
  colorA: 'white',
  colorB: 'black'
};
let natureColors = {
  colorC: 'green',
  colorD: 'yellow'
};
Object.setPrototypeOf(natureColors, simpleColors);
Object.keys(natureColors); // => ['colorC', 'colorD']
natureColors['colorA'];    // => 'white'
natureColors['colorB'];    // => 'black'

Object.keys(natureColors)返回natureColors对象的自身可枚举属性键:[‘colorC’,’colorD’]。

natureColors包含从simpleColors原型对象继承的属性,但是Object.keys()函数会跳过它们。

Object.values() 和 Object.entries() 也都是返回一个给定对象自身可枚举属性的键值对数组

// ...
Object.values(natureColors); 
// => ['green', 'yellow']
Object.entries(natureColors);
// => [ ['colorC', 'green'], ['colorD', 'yellow'] ]

现在注意与for..in语句的区别,for..in不仅可以循环枚举自身属性还可以枚举原型链中的属性

// ...
let enumerableKeys = [];
for (let key in natureColors) {
  enumerableKeys.push(key);
}
enumerableKeys; // => ['colorC', 'colorD', 'colorA', 'colorB']

enumerableKeys数组包含natureColors自身属性键: ‘colorC’和’colorD’。

另外for..in也遍历了从simpleColors原型对象继承的属性

2. Object.values() 返回属性值

来个例子,使用Object.keys()收集keys,然后通过 key 去对象取对应的值:

let meals = {
  mealA: 'Breakfast',
  mealB: 'Lunch',
  mealC: 'Dinner'
};
for (let key of Object.keys(meals)) {
  let mealName = meals[key];
  // ... do something with mealName
  console.log(mealName);
}
// 'Breakfast' 'Lunch' 'Dinner'

meal是一个普通对象。 使用Object.keys(meals)和枚举的for..of循环获取对象键值。

代码看起来很简单,但是,let mealName = meals[key] 没有多大的必要,可以进一步优化,如下:

let meals = {
  mealA: 'Breakfast',
  mealB: 'Lunch',
  mealC: 'Dinner'
};
for (let mealName of Object.values(meals)) {
  console.log(mealName);
}
// 'Breakfast' 'Lunch' 'Dinner'

因为Object.values(meals)返回数组中的对象属性值,所以可以直接在 for..of 中简化。 mealName直接在循环中赋值。

Object.entries()

Object.entries() 返回键值对数组,如 [ [key1, value1], [key2, value2], …, [keyN, valueN] ]。

可能直接使用这些键值对不怎么方便,但可以通过数组解构赋值方式访问键和值就变得非常容易,如下所示:

let meals = {
  mealA: 'Breakfast',
  mealB: 'Lunch',
  mealC: 'Dinner'
};
for (let [key, value] of Object.entries(meals)) {
  console.log(key + ':' + value);
}
// 'mealA:Breakfast' 'mealB:Lunch' 'mealC:Dinner'

如上所示,因为 Object.entries()返回一个与数组解构赋值兼容的集合,因此不需要为赋值或声明添加额外的行。

当普通对象要转换成 Map 时Object.entries() 就很有用,因为Object.entries() 返回的格式与Map构造函数接受的格式完全相同:(key,value)。

使用常规的Map构造函数可以将一个二维键值对数组转换成一个Map对象。

来个例子,让人缓缓:

let greetings = {
  morning: 'Good morning',
  midday: 'Good day',
  evening: 'Good evening'
};
let greetingsMap = new Map(Object.entries(greetings));
greetingsMap.get('morning'); // => 'Good morning'
greetingsMap.get('midday');  // => 'Good day'
greetingsMap.get('evening'); // => 'Good evening'

有趣的是,Map提供了与Object.values()和Object.entries() 等效的方法(只是它们返回Iterators),以便为Map实例提取属性值或键值对:

  • Map.prototype.values() 等价于Object.values()
  • Map.prototype.entries() 等价于Object.entries()

map是普通对象的改进版本,可以获取 map 的大小(对于普通对象,必须手动获取),并使用任意对象类型作为键(普通对象使用字符串基元类型作为键)。

让我们看看返回.values()和.entries()的map的方法:

// ...
[...greetingsMap.values()];
// => ['Good morning', 'Good day', 'Good evening']
[...greetingsMap.entries()];
// => [ ['morning', 'Good morning'], ['midday', 'Good day'], 
//      ['evening', 'Good evening'] ]

注意,greetingsMap.values()和greetingsMap.entries()返回迭代器对象。若要将结果放入数组,扩展运算符…是必要的。

对象属性的顺序

JS 对象是简单的键值映射,因此,对象中属性的顺序是微不足道的, 在大多数情况下,不应该依赖它。

在ES5和早期标准中,根本没有指定属性的顺序。

然而,从ES 6开始,属性的顺序是基于一个特殊的规则的,除非特指按照时间排序。通过两个新方法Object.getOwnPropertyNames和Reflect.ownKeys来编写示例讲解这一属性排序规则。

  • 数字:当属性的类型时数字类型时,会按照数字的从大到小的顺序进行排序;
  • 字符串:当属性的类型是字符串时,会按照时间的先后顺序进行排序;
  • Symbol:当属性的类型是Symbol时,会按照时间的先后顺序进行排序。

如果需要有序集合,建议将数据存储到数组或Set中。

总结

Object.values() 和Object.entries() 是为JS开发人员提供新的标准化辅助函数的另一个改进步骤。

Object.entries()最适用于数组解构赋值,其方式是将键和值轻松分配给不同的变量。 此函数还可以轻松地将纯JS对象属性映射到Map对象中。、

注意,Object.values()和Object.entries()返回数据的顺序是不确定的,所以不要依赖该方式。

海计划公众号
(0)
上一篇 2020/03/29 01:43
下一篇 2020/03/29 01:43

您可能感兴趣的内容

  • React 现代化测试菜鸟知识_测试指南教程

    测试的动机测试用例的书写是一个风险驱动的行为, 每当收到 Bug 报告时, 先写一个单元测试来暴露这个 Bug, 在日后的代码提交中, 若该测试用例是通过的, 开发者就能更为自信地确保程序不会再次出现此 bug。测试的动机是有效地提高开发者的自信心。前端现代化测试模型前端测试中有两种模型, 金字塔模型 与 奖杯模型 。金字塔模型摘自 Martin Fowle

    2020/03/24
  • 绘艺素材指南攻略_国内优质的素材站点

    绘艺素材指南攻略 官方网址:https://www.huiyi8.com/ 简介描述:国内优质的素材站点 绘艺素材网是一家大型综合设计类素材网站,提供矢量素材、图标素材、高清图片素…

    2020/03/06
  • github-markdown-css指南攻略_GitHub Markdown 样式的一个简洁 CSS

    github-markdown-css指南攻略 官方网址:https://sindresorhus.com/github-markdown-css/ GitHub:https://…

    2020/03/06
  • 200行代码实现超轻量级编译器小白知识_代码入门知识

    前言本篇内容主要由 the-super-tiny-compiler中的注释翻译而来,该项目实现了一款包含编译器核心组成的极简的编译器。希望能够给想要初步了解编译过程的同学提供到一些帮助。概要本篇和大家一起学习写一款超级简单轻量,去掉注释只有不到200行代码的编译器。该编译器将类 lisp 语法函数调用 编译为 类C语言函数调用如果不熟悉上述的两种语法的其中任

    2020/03/22
  • layer.open 打开新页面传参问题小白基础_传参小白知识

    如图所示,点击出售,把A页面的数据传到弹框上面,因为弹框比较复杂,所以使用引入一个新页面。A.html a.js B.html b.js1、第一种方案sellInte: function (){var obj = document.getElementById(“first_value”);var num = obj.innerText;layer.open

    2020/03/24
  • csshake小白知识一个使用CSS3实现的动画样式,实现多种不同样式的抖动效果

    csshake基础入门 官方网址:https://elrumordelaluz.github.io/csshake/ GitHub:https://github.com/elrum…

    2020/03/05
  • 浅谈对soket的理解入门基础_soket使用指南

    定义:网络上的两个程序通过一个双向的通信链实现数据的交换,这个链接的一端就成为Socket它是进程通信的一种,即调用这个网络库的api函数实现分布在不同主机相关进程之间的数据交换,依照tcp/ip协议分给每个主机的网络地址,如果两个主机要进行通信,任何一个进程都要首先知道对方的网络地址,也可以说是对方的IP。端口号用来辨别本地进程,一个本地的进程通信时,,都

    2020/04/03
  • SoundJS入门教程_用于处理音频的Javascript库

    SoundJS入门教程 官方网址:http://createjs.com/ GitHub:https://github.com/CreateJS/SoundJS 简介描述:用于处理…

    2020/03/06
  • Js遍历数组时注意 Empty Item 的影响入门指南_数组小白帮助

    这两天碰到个问题:从日志中发现一些来自 iOS 10.3 的报错「Cannot read property ‘xxx’ of undefined」,定位到代码的报错位置,发现是遍历某数组时产生的报错,该数组的元素应该全都是 Object,但实际上出现了异常的元素。排查该数组的来源,的确其元素并不保证都是 Object,问题很容易就解决了。但是,为什么这个报错

    2020/03/26
  • 解决这两种this混乱的场景,让它的指向明明白白!小白指南_this菜鸟教程网

    this永远指向当前函数的主人,在构造函数中this指向新创建的对象,说明构造函数的主人是新创建的对象。但是有以下两种场景会引起this指向的混乱:加了定时器new去创建对象的时候,this指向新创建的对象也就是a1,当我们调用a1.show()的时候输出10。 function Aaa(){this.a = 10;}Aaa.prototype

    2020/03/26
  • Sequence.js攻略教程_一个非常现代的图片滑动插件

    Sequence.js攻略教程 官方网址:http://sequencejs.com GitHub:https://github.com/IanLunn/Sequence 简介描述…

    2020/03/10
  • 现代 js 框架存在的根本原因零基础入门_框架菜鸟攻略

    原文链接: medium.com翻译链接:zcfy.cc我曾见过很多很多人盲目地使用(前端)框架,如 React,Angular 或 Vue等等。这些框架提供了许多有意思的东西,然而通常人们(自以为)使用框架是因为:它们支持组件化;它们有强大的社区支持;它们有很多(基于框架的)第三方库来解决问题;它们有很多(很好的)第三方组件;它们有浏览器扩展工具来帮助调试

    2020/04/05
  • html网页自动跳转方法入门知识整理网页自动跳转的5种方法_网页入门教程

    网页自动跳转,是指当用户访问某个网页时,被自动跳转到另一个网页中去。网页自动跳转的主要作用是,当域名变更后,或者网站里的一个或多个网页被删除后,可以使用这种方式将用户引导到其它正常的网页中去,从而留住用户。不过,现在有许多人利用网页自动跳转来进行作弊,欺骗搜索引擎,从而实现提高网站搜索引擎排名的目的。比较典型的方式是:先做一个“桥页”,当搜索引擎收录了这个桥

    2020/04/05
  • Js柯里化使用教程_柯里化基础知识

    简介柯里化(Currying),又称部分求值(Partial Evaluation),是把接收多个参数的函数变成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受剩余的参数而且返回结果的新函数的技术。核心思想: 把多参数传入的函数拆成单参数(或部分参数)函数,内部再返回调用下一个单参数(或部分参数)函数,依次处理剩余的参数。按照Stoyan Ste

    2020/03/26
  • Webpack 技巧 – 联合 alias 和 mainFields 提高多库联调效率菜鸟知识_技巧入门基础

    1、多库联调场景目前在开发一个工程项目,考虑到可扩展性和功能解耦,将每个功能模块都单独拆分出来。在正式使用、单独维护某个功能包的时候没什么问题,最为头疼的是联调两个功能模块的时候,就比较掣肘了。我们举下面的场景为例来说明:工程项目中有 A、B、C 这 3 个功能模块,每个功能模块都是单独的一个 npm 包;其中 A 是基础工具包,B、C 是业务功能模块;C

    2020/03/30
  • 从零实现TypeScript版Koa指南教程_Koa入门百科

    这篇文章会讲些什么?如何从零开始完成一个涵盖Koa核心功能的Node.js类库从代码层面解释Koa一些代码写法的原因:如中间件为什么必须调用next函数、ctx是怎么来的和一个请求是什么关系我们知道Koa类库主要有以下几个重要特性:支持洋葱圈模型的中间件机制封装request、response提供context对象,方便http操作异步函数、中间件的错误处理

    2020/03/29