104 lines
4.3 KiB
Plaintext
104 lines
4.3 KiB
Plaintext
---
|
||
title: 你用什么语言结构来迭代对象的属性和数组项目?
|
||
---
|
||
|
||
## 对象
|
||
|
||
### `for...in` 语句
|
||
|
||
```js
|
||
for (const property in obj) {
|
||
console.log(property);
|
||
}
|
||
```
|
||
|
||
`for...in`语句重复了对象的所有**可枚举**属性(包括继承的可枚举属性)。 因此,在使用对象前,您应该通过`Object.hasOwn(object, property)`检查该属性是否直接在对象上存在。
|
||
|
||
```js
|
||
for (const property in obj) {
|
||
if (Object.hasOwn(obj, property)) {
|
||
console.log(property);
|
||
}
|
||
}
|
||
```
|
||
|
||
请注意,`obj.hasOwnProperty()` 不推荐,因为它不适用于使用 `Object.create(null)` 创建的对象。 建议在较新的浏览器中使用[`Object.hasOwn()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn) 或者使用好的旧的 `Object.prototype.hasOwnProperty.call(object, key)`。
|
||
|
||
### `Object.keys()`
|
||
|
||
```js
|
||
Object.keys(obj).forEach((property) => {
|
||
console.log(property);
|
||
});
|
||
```
|
||
|
||
`Object.keys()`是一个静态方法,它将返回你传递给它的对象的所有可枚举属性名称的数组。 既然`Object.keys()` 返回数组,你也可以使用下面列出的数组迭代方法进行迭代。
|
||
|
||
_参考资料: [Object.keys() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys)_
|
||
|
||
### `Object.getOwnPropertyNames()`
|
||
|
||
```js
|
||
Object.getOwnPropertyNames(obj).forEach((property) => {
|
||
console.log(property);
|
||
});
|
||
```
|
||
|
||
`Object.getOwnPropertyNames()` 是一种静态方法,它将列出您通过的对象的所有可枚举和不可枚举的属性。 既然`Object.getOwnPropertyNames()` 返回数组,你也可以使用下面列出的数组迭代方法进行迭代。
|
||
|
||
_参考资料: [Object.getOwnPropertyNames() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames)_
|
||
|
||
## 数组
|
||
|
||
### "for" 循环
|
||
|
||
```js
|
||
for (var i = 0; i < arr.length; i++) {
|
||
console.log(arr[i]);
|
||
}
|
||
```
|
||
|
||
一个常见的陷阱是,`var`是在函数范围内,而不是在块范围内,大多数情况下,你想要块范围的迭代器变量。 ES2015引入了`let`,它具有块的范围,建议使用`let`而不是`var`。
|
||
|
||
```js
|
||
for (let i = 0; i < arr.length; i++) {
|
||
console.log(arr[i]);
|
||
}
|
||
```
|
||
|
||
### `Array.prototype.forEach()`
|
||
|
||
```js
|
||
arr.forEach((element, index) => {
|
||
console.log(element, index);
|
||
});
|
||
```
|
||
|
||
如果你不需要使用 "索引",只需要单个数组元素,那么`Array.prototype.forEach()`方法有时会更方便。 然而,缺点是你不能中途停止迭代,提供的函数将在元素上执行一次。 如果你需要更精确地控制迭代,一个 `for` 循环或 `for...of` 语句就更具有相关性。
|
||
|
||
_参考资料: [Array.prototype.forEach() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)_
|
||
|
||
### `for...of` 语句
|
||
|
||
```js
|
||
for (let element of arr) {
|
||
console.log(element);
|
||
}
|
||
```
|
||
|
||
ES2015引入了一种新的迭代方式,即`for-of`循环,它允许你在符合[可迭代协议](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol)的对象上循环,如`String`、`Array`、`Map`、`Set`等。 它将`for` 循环和 `forEach()` 方法的优点结合起来。 “for”循环的优点是你可以从中断开,而 "forEach() "的优点是它比 "for "循环更简明,因为你不需要一个计数器变量。 使用 "for...of "语句,你可以获得从循环中打断的能力和更简洁的语法。
|
||
|
||
大多数时候,更推荐使用`.forEach`方法,但这真的取决于你想做什么。 在 ES2015 之前,当我们需要使用 `break` 提前终止循环时,我们使用了 `for` 循环。 但现在有了ES2015,我们可以通过 `for...of` 语句来做到这一点。 当您需要更多的灵活性时,使用 "for" 循环,例如每个循环多次递增迭代器。
|
||
|
||
另外,在使用`for...of`语句时,如果你需要同时访问每个数组元素的索引和值,你可以用ES2015的`Array.prototype. entries()`方法来实现:
|
||
|
||
```js
|
||
const arr = ['a', 'b', 'c'];
|
||
|
||
for (let [index, elem] of arr.entries()) {
|
||
console.log(index, ': ', elem);
|
||
}
|
||
```
|
||
|
||
_参考资料: [for...of - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)_
|