front-end-interview-handbook/packages/quiz/questions/what-language-constructs-do.../zh-CN.mdx

104 lines
4.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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)_