• JS中轻松遍历对象属性的几种方式


    自身可枚举属性

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

    eg:

    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.setPrototypeOf() 方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或 null

    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.values()**方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。

    来个例子,使用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()**方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)。

    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()返回一个与数组解构赋值兼容的集合,因此不需要为赋值或声明添加额外的行。

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

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

    eg:

    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 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

    有趣的是,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.getOwnPropertyNamesReflect.ownKeys来编写示例讲解这一属性排序规则。

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

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

    总结

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

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

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


    链接:https://juejin.im/post/5d48c275f265da03b12032a1

  • 相关阅读:
    [NOI2015]程序自动分析
    D-query(莫队)
    小B的询问
    组合的输出 (dfs+记忆化)
    组合的输出 (dfs+记忆化)
    5719: 集合的划分(dfs)
    Search for a range, 在一个可能有重复元素的有序序列里找到指定元素的起始和结束位置
    Find Min In Rotated Sorted Array2,包含重复数字的反转序列找最小值。
    Find Min In Rotated Sorted Array,寻找反转序列中最小的元素。
    Search In Rotated SortedArray2, 有重复数据的反转序列。例如13111.
  • 原文地址:https://www.cnblogs.com/baixiaoxiao/p/11307031.html
Copyright © 2020-2023  润新知