zoukankan      html  css  js  c++  java
  • javascript遍历对象的几种方法

    总结下在JavaScript中遍历对象的几种方法。

    for in

    for in循环是最基础的遍历对象的方式,除了能拿到到对象自身的属性之外,它还能拿到对象原型链上的属性。

    // 创建一个对象并指定其原型,yanggb为原型上的属性
    const obj = Object.create({
     yanggb: 'yanggb'
    })
     
    // yanggb1为对象自身的属性
    obj.yanggb1 = 'yanggb1'
     
    for (let key in obj) {
     console.log(obj[key]) // yanggb1, yanggb
    }

    可以看到对象原型上的属性也被循环出来了,首先是遍历了自身的属性,然后逐层往上遍历原型链上原型的属性。

    如果想要过滤掉原型链上的属性,也可以使用对象的hasOwnProperty()方法判断其是否是自身属性,以此来达到只针对自身的属性做相应操作的目的。

    for (let key in obj) {
     if (obj.hasOwnProperty(key)) {
      console.log(obj[key]) // yanggb1
     }
    }

    这时候原型上的yanggb属性就被过滤掉了。

    Object.keys

    Object.keys()是ES5新增的一个对象方法,该方法返回对象自身属性名组成的数组,它会自动过滤掉原型链上的属性,然后可以通过数组的forEach()方法来遍历。

    Object.keys(obj).forEach((key) => {
     console.log(obj[key]) // yanggb1
    })

    此外还有Object.values()方法和Object.entries()方法,这两方法的作用范围和Object.keys()方法类似,分别是取得对象的属性值数组和属性键值数组数组。

    for in循环和Object.keys()方法一样,都不会返回对象的不可枚举属性,如果需要遍历不可枚举的属性,就要使用Object.getOwnPropertyNames()方法了。

    Object.getOwnPropertyNames

    Object.getOwnPropertyNames()同样也是ES5新增的一个对象方法,该方法会返回对象自身属性名组成的数组,包括不可枚举的属性,因此也可以通过数组的forEach()方法来遍历。

    // 创建一个对象并指定其原型,yanggb为原型上的属性
    // yanggb1为对象自身的属性并且不可枚举
    const obj = Object.create({
     yanggb: 'yanggb'
    }, {
     yanggb1: {
      value: 'yanggb1',
      enumerable: false
     }
    })
     
    obj.yanggb2 = 'yanggb2'
     
    // 不包括不可枚举的yanggb1属性
    Object.keys(obj).forEach((key) => {
     console.log(obj[key]) // yanggb1
    })
     
    // 包括不可枚举的yanggb1属性
    Object.getOwnPropertyNames(obj).forEach((key) => {
     console.log(obj[key]) // yanggb1,yanggb2
    })

    而在ES2015新增了Symbol数据类型,该类型可以作为对象的键。针对该类型,ES2015同样新增了一个Object.getOwnPropertySymbols()方法。

    Object.getOwnPropertySymbols

    Object.getOwnPropertySymbols()方法返回对象自身的Symbol属性组成的数组,不包括字符串属性等其他属性。

    Object.getOwnPropertySymbols(obj).forEach((key) => {
     console.log(obj[key])
    })

    此时什么都没有输出,因为该对象还没有Symbol属性。

    // 给对象添加一个不可枚举的Symbol属性
    Object.defineProperties(obj, {
     [Symbol('yanggb')]: {
      value: 'Symbol yanggb',
      enumerable: false
     }
    })
     
    // 给对象添加一个可枚举的Symbol属性
    obj[Symbol('yanggb1')] = 'Symbol yanggb1'
     
    Object.getOwnPropertySymbols(obj).forEach((key) => {
     console.log(obj[key]) // Symbol yanggb, Symbol yanggb1
    })

    这时候就会输出所有的Symbol属性,包括可枚举不可枚举Symbol属性。

    Reflect.ownKeys

    Reflect.ownKeys()方法是ES2015新增的一个静态方法,该方法返回对象自身所有属性名组成的数组,包括不可枚举的属性和Symbol属性。

    Reflect.ownKeys(obj).forEach((key) => {
     console.log(obj[key]) // yanggb, yanggb1, Symbol yanggb, Symbol yanggb1
    })

    既然方法有那么多,自然需要对比一下才能知道不同的场景该怎么选用。

    几种方法的对比

    通过一个表格直观得对比:

    方式 基本属性 原型链 不可枚举 Symbol
    for in
    Object.keys()
    Object.getOwnPropertyNames()
    Object.getOwnPropertySymbols()
    Reflect.ownKeys()

    这其中只有for in循环会得到对象原型链上的属性,其它方法都只适用于对象自身的属性。

    ES语言后续添加的新特性不会对以前的代码产生副作用,比如在ES2015之前就存在的for in循环,Object.keys()和Object.getOwnPropertyNames()是肯定不会返回Symbol属性的。

    "成长的经历,大概能让人变得越来越安静。"

  • 相关阅读:
    Selenium webdriver 操作日历控件
    selenuim-webdriver注解之@FindBy、@FindBys、@FindAll的区别
    配置 mybatis的 log4j.properties
    查询在一个数据库中某个字段存在于哪些表
    Linux下修改Mysql的用户(root)的密码
    MySQL——修改root密码的4种方法(以windows为例)
    报错:1130-host ... is not allowed to connect to this MySql server 开放mysql远程连接 不使用localhost
    C++中的static 成员变量的一些注意点
    #pragma once与#ifndef的区别
    C++类中的成员函数和构造函数为模板函数时的调用方法
  • 原文地址:https://www.cnblogs.com/yanggb/p/13568354.html
Copyright © 2011-2022 走看看