JavaScript对象迭代方法和性能的比较


本文摘自PHP中文网,作者hzc,侵删。

Object.entries


返回对象所有可枚举的键值对,不会追寻原型链上的 key

1

2

3

4

5

6

7

8

9

10

let obj = {

  key1: 'value1',

  key2: 'value2',

  key3: 'value3',

}

Object.entries(obj).forEach(entry => {

  let key = entry[0]

  let value = entry[1]

  // entry 会是这样 ["key1", "value1"]

})

Object.keys


返回对象所有可枚举的键

1

2

3

4

5

6

7

8

let obj = {

  key1: 'value1',

  key2: 'value2',

  key3: 'value3',

}

Object.keys(obj).forEach(key => {

  let value = obj[key]

})

Object.values


返回对象所有可枚举的值

1

2

3

4

5

6

7

8

let obj = {

  key1: 'value1',

  key2: 'value2',

  key3: 'value3',

}

Object.values(obj).forEach(value => {

  // 只能使用 value

})

for…in loop


迭代可枚举属性,会顺着原型链找下去

1

2

3

4

5

6

7

8

9

10

11

12

13

let obj = {

  key1: 'value1',

  key2: 'value2',

  key3: 'value3',

}

for (const key in obj) {

  let value = obj[key]

  if (obj.hasOwnProperty(key)) {

    // 本身的

  } else {

    // 来自原型链的

  }

}

Object.getOwnPropertyNames


返回对象所有(包括不可枚举)的键(原文说会找原型链是错的)

1

2

3

4

5

6

7

8

let obj = {

  key1: 'value1',

  key2: 'value2',

  key3: 'value3',

}

Object.getOwnPropertyNames(obj).forEach(key => {

  let value = obj[key]

})

性能比较


下面的代码用上面的几种方法遍历有 1000000 个属性的对象,循环 10 次

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

const { PerformanceObserver, performance } = require('perf_hooks')

 

let objectSize = 1000000

let iterations = 10

 

console.log(

  'Starting performance test with %d object size and %d iterations',

  objectSize,

  iterations

)

 

let values = {

  ENTRIES: 0,

  KEYS: 0,

  VALUES: 0,

  FORIN: 0,

  GETOWP: 0,

}

 

const obs = new PerformanceObserver(items => {

  let entry = items.getEntries()[0]

  console.log(entry.name, entry.duration)

  values[entry.name] += entry.duration

  performance.clearMarks()

})

obs.observe({ entryTypes: ['measure'] })

 

function generateObject() {

  let obj = {}

  for (let i = 0; i < objectSize; i++) {

    obj['key' + Math.random()] = 'val' + Math.random()

  }

  return obj

}

 

for (let i = 0; i < iterations; i++) {

  let obj = generateObject()

 

  //Object.entries

  performance.mark('A')

  Object.entries(obj).forEach(entry => {

    let key = entry[0]

    let value = entry[1]

  })

  performance.mark('B')

  performance.measure('ENTRIES', 'A', 'B')

 

  //Object.Keys

  performance.mark('A')

  Object.keys(obj).forEach(key => {

    let value = obj[key]

  })

  performance.mark('B')

  performance.measure('KEYS', 'A', 'B')

 

  //Object.Values

  performance.mark('A')

  Object.values(obj).forEach(value => {})

  performance.mark('B')

  performance.measure('VALUES', 'A', 'B')

 

  //For In

  performance.mark('A')

  for (const key in obj) {

    let value = obj[key]

  }

  performance.mark('B')

  performance.measure('FORIN', 'A', 'B')

 

  //Object.getOwnPropertyNames

  performance.mark('A')

  Object.getOwnPropertyNames(obj).forEach(key => {

    let value = obj[key]

  })

  performance.mark('B')

  performance.measure('GETOWP', 'A', 'B')

}

 

console.log(

  Object.entries(values).sort((a, b) => {

    return a[1] - b[1]

  })

)

下面的结果是我自己跑的,顺序的是指赋值的时候直接用 index,随机则是键值对都插入随机数,得到的性能排序是和作者一样的,也因为 node.js 和 chrome 都是 V8,所以这个应该也是代表在浏览器上的性能排序。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// 顺序

;[

  ['FORIN', 4677.321499],

  ['KEYS', 4812.776572],

  ['GETOWP', 8610.906197],

  ['VALUES', 9914.674390999999],

  ['ENTRIES', 19338.083694],

]

 

// 随机

;[

  ['KEYS', 4502.579589],

  ['FORIN', 4678.013548000001],

  ['GETOWP', 8880.325031999999],

  ['VALUES', 10104.106962],

  ['ENTRIES', 17089.637588999998],

]

之前听说引擎会猜测下一个值让运行速度更快,看数据似乎没有太大影响。

也算是一点干货,快点来原文给作者鼓鼓掌吧

推荐教程:《JS教程》

以上就是JavaScript对象迭代方法和性能的比较的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

通过javascript函数生成字符串的所有排列组合

js如何读取和保存文件?方法介绍

vue源码之目录结构的简单分析

javascript alert函数显示中文乱码怎么办

使用canvas实现迷宫游戏

为什么javascript小数相减会出现一长串的小数位数?

javascript函数是什么

javascript的this的用法详解

javascript怎么删除li

javascript失去焦点如何设置

更多相关阅读请进入《javascript》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...