首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在JS中,可迭代和可枚举之间有什么区别?我正在进行For/of和For/In循环,这些术语经常出现。

在JS中,可迭代和可枚举之间有什么区别?我正在进行For/of和For/In循环,这些术语经常出现。
EN

Stack Overflow用户
提问于 2021-08-04 08:32:10
回答 1查看 2.7K关注 0票数 7

我在学习循环/in和For/of时遇到了术语Iterable和Enumerable。对象应该是可枚举的,我们必须使用For/in循环来循环对象的属性,并在数组和字符串上使用For/of循环。我无法理解这两个术语。这两者有什么区别呢?

EN

回答 1

Stack Overflow用户

发布于 2021-08-04 09:42:39

Iterable适用于值

值可以是可迭代的,也可以是不可迭代的。它需要实现众所周知的符号@@iterator@@asyncIterator。实现的方法还必须通过返回迭代器来实现可迭代协议。有了这些功能之后,就可以通过将这些值作为可以迭代的东西来处理,从而实现特殊的交互(因此可以使用“可迭代”的名称)。下面是一些示例:

for...of

可迭代性最基本、也可能是最常见的用途是对它们进行迭代。for...of循环将这样做,并从迭代器中获取项,直到没有剩下的项为止。

弦乐:

代码语言:javascript
运行
复制
const str = "hello world";

for (const char of str)
  console.log(char);
代码语言:javascript
运行
复制
.as-console-wrapper { max-height: 100% !important; }

数组

代码语言:javascript
运行
复制
const arr = ["a", "b", "c", "d"];

for (const item of arr)
  console.log(item);
代码语言:javascript
运行
复制
.as-console-wrapper { max-height: 100% !important; }

自定义对象

代码语言:javascript
运行
复制
const iterable = {
  [Symbol.iterator]() {
    let repeat = 0;
    return {
      next() {
        return {
          value: 42, 
          done: repeat++ >= 3
        };
      }
    }
  }
}

for (const item of iterable)
  console.log(item);
代码语言:javascript
运行
复制
.as-console-wrapper { max-height: 100% !important; }

...

当扩展值时,将使用迭代器,您将得到来自该迭代器的每个值的一些信息。例如,扩展到数组中,[...value]将创建一个具有所有值的数组。扩展到一个函数调用中,fn(...value)将以每个项作为参数调用该函数。

字符串

代码语言:javascript
运行
复制
const str = "hello world";

console.log([...str]); //spread into array
console.log(...str);   //spread into function call
代码语言:javascript
运行
复制
.as-console-wrapper { max-height: 100% !important; }

数组

代码语言:javascript
运行
复制
const arr = ["a", "b", "c", "d"];

console.log([...arr]); //spread into array
console.log(...arr);   //spread into function call
代码语言:javascript
运行
复制
.as-console-wrapper { max-height: 100% !important; }

自定义对象

代码语言:javascript
运行
复制
const iterable = {
  [Symbol.iterator]() {
    let repeat = 0;
    return {
      next() {
        return {
          value: 42, 
          done: repeat++ >= 3
        };
      }
    }
  }
}

console.log([...iterable]); //spread into array
console.log(...iterable);   //spread into function call
代码语言:javascript
运行
复制
.as-console-wrapper { max-height: 100% !important; }

阵列破坏

这个名字可能有点误导。数组析构总是使用对象的迭代器。这并不意味着它只能用于数组。

字符串

代码语言:javascript
运行
复制
const str = "hello world";

const [first, second] = str;
console.log(first, second);
代码语言:javascript
运行
复制
.as-console-wrapper { max-height: 100% !important; }

数组

代码语言:javascript
运行
复制
const arr = ["a", "b", "c", "d"];

const [first, second] = arr;
console.log(first, second);
代码语言:javascript
运行
复制
.as-console-wrapper { max-height: 100% !important; }

自定义对象

代码语言:javascript
运行
复制
const iterable = {
  [Symbol.iterator]() {
    let repeat = 0;
    return {
      next() {
        return {
          value: 42, 
          done: repeat++ >= 3
        };
      }
    }
  }
}

const [first, second] = iterable;
console.log(first, second);
代码语言:javascript
运行
复制
.as-console-wrapper { max-height: 100% !important; }

枚举用于对象属性。

只能枚举对象属性。没有任何价值。这可以通过使用Object.defineProperty()Object.defineProperties()Reflect.defineProperty()Object.create()进行配置。

不可枚举对象属性

很难得到一个详尽的列表,但这传达了这样的想法:不可枚举的属性被排除在属性上的一些“批量”操作之外。

但是,不可枚举的属性仍然可以直接访问.它们不是“隐藏”或“私有”,只是没有出现最常见的机制来抓取所有属性。

代码语言:javascript
运行
复制
const obj = Object.defineProperties({}, {
  "a": { value: 1, enumerable: true},
  "b": { value: 2, enumerable: false},
  "c": { value: 3, enumerable: true},
});

for (const prop in obj)
  console.log("for...in:", prop); //a, c
  
console.log("Object.keys():", Object.keys(obj));     // [ "a", "c" ]
console.log("Object.values():", Object.values(obj)); // [ 1, 3 ]

const clone1 = {...obj};
console.log("clone1:", clone1);               // { "a": 1, "c": 3 }
console.log('"b" in clone1:', "b" in clone1); // false
console.log("clone1.b:", clone1.b);           // undefined

const clone2 = Object.assign({}, obj);
console.log("clone2:", clone2);               // { "a": 1, "c": 3 }
console.log('"b" in clone2:', "b" in clone2); // false
console.log("clone2.b:", clone2.b);           // undefined

//still accessible
console.log('"b" in obj:', "b" in obj); // true
console.log("obj.b:", obj.b);           // 2
代码语言:javascript
运行
复制
.as-console-wrapper { max-height: 100% !important; }

还有一些机制允许查看不可枚举的属性:例如,Object.getOwnPropertyNames()Object.getOwnPropertyDescriptors()将能够显示它们。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68647965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档