JavaScript中数组与对象的遍历方法

数组

for循环

最传统的方法,按下标存取,也是最高效的方法

1
2
3
4
5
6
7
8
9
10
11
12
let arr = [1,2,3,4]
for(let i = 0; i < arr.length; i++){
console.log(arr[i])
}

//1,2,3,4

//不用每次计算len,更加高效
for(let i = 0, let len = arr.length; i < len; i++){
console.log(arr[i])
}
//1,2,3,4

for…of循环

for...of语句创建一个迭代器(ES6引入,迭代器只会便利可枚举属性)。每一次循环都会调用迭代器的next对象。并返回当前该迭代器的值。

1
2
3
4
5
6
let arr = [1,2,3,4]
for(let val of arr){
console.log(val)
}

//1,2,3,4

另外只要实现了迭代器的数据才能使用for...of循环。具体有:ArrayMapsSetStringArguments Object参数对象Generators(生成器)

for…in循环

for...in语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性。

1
2
3
4
5
6
let arr = [1,2,3,4]
for(let i in arr){
console.log(i)
}

//0,1,2,3

注意:

  1. for ...in循环遍历得到的结果为数据的键(数组即为下标)。
  2. 数组最好不要用for...in,因为for...in循环是为遍历对象而且设计的。
  3. 该方法也可用于String遍历下标。
  4. for...in会顺着原型链向上遍历,原型链上所有的可遍历对象都会被遍历。比如(定义Array.prototype.max = () => {...}来获取数组中最大值,如果这么定义,那么这个属性也会被for...in纳入遍历)

Array.prototype.entries()

该方法一个新的 Array 迭代器对象。Array Iterator是对象,它的原型(proto:Array Iterator)上有一个next方法,可用用于遍历迭代器取得原数组的[key,value]。

1
2
3
4
5
6
7
8
9
10
var arr = ["a", "b", "c"];
var iterator = arr.entries();
console.log(iterator);

/*Array Iterator {}
__proto__:Array Iterator
next:ƒ next()
Symbol(Symbol.toStringTag):"Array Iterator"
__proto__:Object
*/

用法一(直接使用Iteratornext对象):

1
2
3
4
5
6
7
8
9
10
const array1 = ['a', 'b', 'c'];

const iterator1 = array1.entries();

console.log(iterator1.next().value);
// expected output: Array [0, "a"]

console.log(iterator1.next().value);
// expected output: Array [1, "b"]

用法二(二维数组按行排序):

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
function sortArr(arr) {
var goNext = true;
var entries = arr.entries();
while (goNext) {
var result = entries.next();
if (result.done !== true) {
result.value[1].sort((a, b) => a - b);
goNext = true;
} else {
goNext = false;
}
}
return arr;
}

var arr = [[1,34],[456,2,3,44,234],[4567,1,4,5,6],[34,78,23,1]];
sortArr(arr);

/*(4) [Array(2), Array(5), Array(5), Array(4)]
0:(2) [1, 34]
1:(5) [2, 3, 44, 234, 456]
2:(5) [1, 4, 5, 6, 4567]
3:(4) [1, 23, 34, 78]
length:4
__proto__:Array(0)
*/

法三(使用for…of 循环)最典型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var arr = ["a", "b", "c"];
var iterator = arr.entries();

for (let v of iterator) {
console.log(v);
}
// [0, "a"]
// [1, "b"]
// [2, "c"]

for (let [index, value] of iterator) {
console.log(index+'---'+value);
}

// 0-"a"
// 1-"b"
// 2-"c"

Array.prototype.keys()

keys() 方法返回一个包含数组中每个索引键的Array Iterator对象。

与上面的Array.prototype.entries()相同,只是遍历的是索引键。用法与上面完全一致,本质也是迭代器。

典型用法(结合for...of):

1
2
3
4
5
6
7
let arr = [1,2,3,4]

for(let i of arr.keys()){
console.log(i)
}

//0,1,2,3

Array.prototype.values()

values() 方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值

与上面的Array.prototype.entries()相同,只是遍历的是索引键。用法与上面完全一致,本质也是迭代器。

典型用法(结合for...of):

1
2
3
4
5
6
7
const arr = ['a', 'b', 'c'];

for (const value of arr.values()) {
console.log(value);
}

//a,b,c

Array.prototype.every()

**every()**方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。

其接收一个回调函数callbackcallback 在被调用时可传入三个参数:元素值,元素的索引,原数组。

every 不会改变原数组。

every 和数学中的”所有”类似,当所有的元素都符合条件才会返回true正因如此,若传入一个空数组,无论如何都会返回 true。(这种情况属于无条件正确:正因为一个空集合没有元素,所以它其中的所有元素都符合给定的条件。)

注意:若收到一个空数组,此方法在一切情况下都会返回 true

典型用法:

1
2
3
4
5
6
7
8
9
10
11
12
let arr = [5,6,4,7,8]
arr.every((value, index, arr) => {
return value > 3
})

//true(因为所有的value都大于3)

arr.every((value, index, arr) => {
return value > 5
})

//false(其中4,5不满足条件)

every方法不会改变数组。

Pollyfill(最基础,下同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if (!Array.prototype.every) {
Object.defineProperty(Array.prototype, 'every', {
enumerable: false,
value: function (callback) {
if (this === null) {
throw new TypeError(
'Array.prototype.every ' + 'called on null or undefined'
);
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
let res = true;
for (let [i, v] of this.entries()) {
if (!callback(v)) {
res = false;
break;
}
}
return res;
},
});
}

Array.prototype.some()

这个方法与上面的方法使用方法完全相同,但是所用相反,**some()**方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。

其接收一个回调函数callbackcallback 在被调用时可传入三个参数:元素值,元素的索引,原数组。

注意:如果用一个空数组进行测试,在任何情况下它返回的都是false

典型用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
let arr = [6,9,3,4]

arr.some((value, index, arr) => {
return value > 8
})

//true(因为存在一个9大于8)

arr.some((value, index, arr) => {
return value > 12
})

//false(因为所有的value都小于12)

some方法不会改变数组。

Pollyfill

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if(!Array.prototype.some){
Object.defineProperty(Array.prototype, 'some', {
enumerable: false,
value: function (callbakc) {
if (this === null) {
throw new TypeError(
'Array.prototype.some ' + 'called on null or undefined'
);
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
let res = false;
for (let [i, v] of this.entries()) {
if (callbakc(v, i, this)) {
res = true;
break;
}
}
return res;
},
});
}

Array.prototype.filter()

filter() 方法创建一个新数组, 其包含通过所提供函数实现的过滤的所有元素的结果。

接收:一个回调函数,函数包含3个参数。value(元素的值),index(元素的索引),arr(被遍历的数组本身)

返回:一个数组,包含所有的元素的检测结果。

1
2
3
4
5
6
7
let arr = [1, 2, 3, 4]

arr.filter((value, index, arr) => {
return value > 2
})

//[3, 4]

该方法可用于剔除不合法数据,比如

1
2
3
4
5
6
7
let arr = [1,2,3, undefined, null, 4, 5]

arr.filter((value, index, arr) => {
return value != undefined && value != null
})

//[1, 2, 3, 4, 5]

flter方法不会改变数组。

Pollyfill

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if (!Array.prototype.filter) {
Object.defineProperty(Array.prototype, 'filter', {
enumerable: false,
value: function (callback) {
if (this === null) {
throw new TypeError(
'Array.prototype.filter ' + 'called on null or undefined'
);
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
let res = [];
for (let i = 0; i < this.length; i++) {
if (callback(this[i])) {
res.push(this[i]);
}
}
return res;
},
});
}

Array.prototype.find()

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined

接收:一个回调函数,函数包含3个参数。value(元素的值),index(元素的索引),arr(被遍历的数组本身)

返回:数组中满足提供的测试函数的第一个元素的值。

1
2
3
4
5
6
7
let arr = [1,2,3,4]

arr.find((value, index, arr) => {
return value > 2
})

//2(由于3,4均大于2,但是3是第一个,所以返回3的下标2)

find方法不会改变数组。

Pollyfill

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
enumerable: false,
value: function (callback) {
if (this === null) {
throw new TypeError(
'Array.prototype.find ' + 'called on null or undefined'
);
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
let res = undefined;
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
res = this[i];
break;
}
}
return res;
},
});
}

Array.prototype.findIndex()

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

接收:一个回调函数,函数包含3个参数。value(元素的值),index(元素的索引),arr(被遍历的数组本身)

返回:数组中满足提供的测试函数的最后一个元素的值。

1
2
3
4
5
6
7
let arr = [1,2,3,4]

arr.find((value, index, arr) => {
return value > 2
})

//3(由于3,4均大于2,但是4是最后一个,所以返回4的下标3)

Pollyfill

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

if (!Array.prototype.findIndex) {
Object.defineProperty(Array.prototype, 'findIndex', {
enumerable: false,
value: function (callback) {
if (this === null) {
throw new TypeError(
'Array.prototype.findIndex ' + 'called on null or undefined'
);
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
let res = -1;
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
res = i;
break;
}
}
return res;
},
});
}

Array.prototype.forEach()

**forEach()**方法对数组的每个元素执行一次给定的函数。

接收:一个回调函数,函数包含3个参数。value(元素的值),index(元素的索引),arr(被遍历的数组本身)

返回undefined

forEach() 为每个数组元素执行一次 callback 函数;与 map() 或者 reduce() 不同的是,它总是返回 undefined 值,并且不可链式调用。其典型用例是在一个调用链的最后执行副作用(side effects,函数式编程上,指函数进行 返回结果值 以外的操作)。

forEach 不会直接改变调用它的对象,但是那个对象可能会被 callback 函数改变。

示例:

1
2
3
4
5
6
7
8
let arr = [1, 2, 3, 4]
let res = []

arr.forEach((value, index, arr) => {
res.push(value*2)
})

console.log(res) //[2,4,6,8]

Pollyfill

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if (!Array.prototype.forEach) {
Object.defineProperty(Array.prototype, 'forEach', {
enumerable: false,
value: function (callback) {
if (this === null) {
throw new TypeError(
'Array.prototype.forEach ' + 'called on null or undefined'
);
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
for (let i = 0; i < this.length; i++) {
callback(this[i], i, this);
}
},
});
}

Array.prototype.map()

**map()**方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。(forEach类似,区别是forEach不用返回,一起操作都在回调函数中进行)

接收:一个回调函数,函数包含3个参数。value(元素的值),index(元素的索引),arr(被遍历的数组本身)

返回:一个由原数组每个元素执行回调函数的结果组成的新数组

上面的示例重写:

1
2
3
4
5
let arr = [1, 2, 3, 4]
let res = arr.map((value, index, arr) => {
return value * 2
})
console.log(res) //[2, 4, 6, 8]
  1. callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。
  2. 因为map生成一个新数组,当你不打算使用返回的新数组却使用map是违背设计初衷的,请用forEach或者for-of替代。
  3. map 不修改调用它的原数组本身(当然可以在 callback 执行时改变原数组)
  4. 根据规范中定义的算法,如果被map调用的数组是离散的(如:arr = [emptyx2, 3]),新数组将也是离散的保持相同的索引为空。

Pollyfill

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if (!Array.prototype.map) {
Object.defineProperty(Array.prototype, 'map', {
enumerable: false,
value: function (callback) {
if (this === null) {
throw new TypeError(
'Array.prototype.map ' + 'called on null or undefined'
);
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
let res = [];
for (let i = 0; i < this.length; i++) {
res.push(callback(this[i], i, this));
}
return res;
},
});
}

Array.prototype.reduce()

reduce()方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

接受:函数累计处理的结果reducer 函数接收4个参数:

  1. Accumulator (acc) (累计器)
  2. Current Value (cur) (当前值)
  3. Current Index (idx) (当前索引)
  4. Source Array (src) (源数组)

callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。

返回值:函数累计处理的结果

示例:

  1. 数组里所有值的和
1
2
3
4
var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) {
return accumulator + currentValue;
}, 0);
// 和为 6
  1. 累加对象数组里的值

要累加对象数组中包含的值,必须提供初始值,以便各个item正确通过你的函数。

1
2
3
4
5
6
var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) {
return accumulator + currentValue.x;
},initialValue)

console.log(sum) // logs 6

你也可以写成箭头函数的形式:

1
2
3
4
5
6
7
var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(
(accumulator, currentValue) => accumulator + currentValue.x
,initialValue
);

console.log(sum) // logs 6
  1. 计算数组中每个元素出现的次数
1
2
3
4
5
6
7
8
9
10
11
12
13
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];

var countedNames = names.reduce(function (allNames, name) {
if (name in allNames) {
allNames[name]++;
}
else {
allNames[name] = 1;
}
return allNames;
}, {});
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

Polyfill

reduce 被添加到 ECMA-262 标准第 5 版,因此它在某些实现环境中可能不被支持。把下面的代码添加到脚本开头可以解决此问题,从而允许在那些没有原生支持 reduceRight 的实现环境中使用它。

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
// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
// https://tc39.github.io/ecma262/#sec-array.prototype.reduce
if (!Array.prototype.reduce) {
Object.defineProperty(Array.prototype, 'reduce', {
value: function(callback /*, initialValue*/) {
if (this === null) {
throw new TypeError( 'Array.prototype.reduce ' +
'called on null or undefined' );
}
if (typeof callback !== 'function') {
throw new TypeError( callback +
' is not a function');
}

// 1. Let O be ? ToObject(this value).
var o = Object(this);

// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;

// Steps 3, 4, 5, 6, 7
var k = 0;
var value;

if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k < len && !(k in o)) {
k++;
}

// 3. If len is 0 and initialValue is not present,
// throw a TypeError exception.
if (k >= len) {
throw new TypeError( 'Reduce of empty array ' +
'with no initial value' );
}
value = o[k++];
}

// 8. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kPresent be ? HasProperty(O, Pk).
// c. If kPresent is true, then
// i. Let kValue be ? Get(O, Pk).
// ii. Let accumulator be ? Call(
// callbackfn, undefined,
// « accumulator, kValue, k, O »).
if (k in o) {
value = callback(value, o[k], k, o);
}

// d. Increase k by 1.
k++;
}

// 9. Return accumulator.
return value;
}
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//concise method     
if (!Array.prototype.reduce) {
Object.defineProperty(Array.prototype, 'reduce', {
enumerable: false,
value: function (callback) {
if (this === null) {
throw new TypeError(
'Array.prototype.map ' + 'called on null or undefined'
);
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
let count = 0;
for (let i = 0; i < this.length; i++) {
count += callback(count, this[i], i, this);
}
},
});
}

Array.prototype.reduceRight()

这个方法与Array.prototype.reduce()只是执行顺序上相反(从右到左)。

**reduceRight()**方法接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。

接收:一个回调函数,函数包含3个参数。value(元素的值),index(元素的索引),arr(被遍历的数组本身)

求一个数组中所有值的和

1
2
3
4
var sum = [0, 1, 2, 3].reduceRight(function(a, b) {
return a + b;
});
// sum is 6 (虽然结果相同,但是是从右到左加)

展示 reducereduceRight 之间的区别

1
2
3
4
5
6
var a = ['1', '2', '3', '4', '5'];
var left = a.reduce(function(prev, cur) { return prev + cur; });
var right = a.reduceRight(function(prev, cur) { return prev + cur; });

console.log(left); // "12345"
console.log(right); // "54321"

Polyfill

reduceRight 被添加到 ECMA-262 标准第 5 版,因此它在某些实现环境中可能不被支持。把下面的代码添加到脚本开头可以解决此问题,从而允许在那些没有原生支持 reduceRight 的实现环境中使用它。

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
// Production steps of ECMA-262, Edition 5, 15.4.4.22
// Reference: http://es5.github.io/#x15.4.4.22
if ('function' !== typeof Array.prototype.reduceRight) {
Array.prototype.reduceRight = function(callback /*, initialValue*/) {
'use strict';
if (null === this || 'undefined' === typeof this) {
throw new TypeError('Array.prototype.reduceRight called on null or undefined');
}
if ('function' !== typeof callback) {
throw new TypeError(callback + ' is not a function');
}
var t = Object(this), len = t.length >>> 0, k = len - 1, value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k >= 0 && !(k in t)) {
k--;
}
if (k < 0) {
throw new TypeError('reduceRight of empty array with no initial value');
}
value = t[k--];
}
for (; k >= 0; k--) {
if (k in t) {
value = callback(value, t[k], k, t);
}
}
return value;
};
}

下面是几种遍历方法的时间对比,可以看出传统for...耗时最少,;for...in最差。

循环遍历

对象

for…in方法

上面已经提到了for...in方法用于遍历数据的索引键。所以这个方法也可以用于遍历对象,具体方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
let obj = {a : 1, b : 2, c : 3, d : 4}

for(let i in obj){
console.log(`${i}---${obj[i]}`)
}

/*
*a---1
*b---2
*c---3
*d---4
*/

Object.entries()

**Object.entries()**方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。

参数

  • obj

    可以返回其可枚举属性的键值对的对象。

返回值

Object.entries()返回一个数组,其元素是与直接在object上找到的可枚举属性键值对相对应的数组。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。

示例

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
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

// array like object
const obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

// array like object with random key ordering
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

// getFoo is property which isn't enumerable
const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } });
myObj.foo = 'bar';
console.log(Object.entries(myObj)); // [ ['foo', 'bar'] ]

// non-object argument will be coerced to an object
console.log(Object.entries('foo')); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]

// iterate through key-value gracefully
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});

Object.keys()

**Object.keys()**方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。

参数

  • obj

    要返回其枚举自身属性的对象。

返回值

一个表示给定对象的所有可枚举属性(索引键)的字符串数组。

描述

Object.keys 返回一个所有元素为字符串的数组,其元素来自于从给定的object上面可直接枚举的属性(索引键)。这些属性的顺序与手动遍历该对象属性时的一致。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// simple array
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']

// array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

// array like object with random key ordering
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']

// getFoo is a property which isn't enumerable
var myObj = Object.create({}, {
getFoo: {
value: function () { return this.foo; }
}
});
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: ['foo']

Object.values()

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

参数

  • obj

    被返回可枚举属性值的对象。

返回值

一个包含对象自身的所有可枚举属性值的数组。

描述

Object.values()返回一个数组,其元素是在对象上找到的可枚举属性值。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

// array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']

// array like object with random key ordering
// when we use numeric keys, the value returned in a numerical order according to the keys
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']

// getFoo is property which isn't enumerable
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = 'bar';
console.log(Object.values(my_obj)); // ['bar']

// non-object argument will be coerced to an object
console.log(Object.values('foo')); // ['f', 'o', 'o']

本文大部分参考了MDN

Powered by Hexo and Hexo-theme-hiker

Copyright © 2019 - 2024 My Wonderland All Rights Reserved.

UV : | PV :