我在学习循环/in和For/of时遇到了术语Iterable和Enumerable。对象应该是可枚举的,我们必须使用For/in循环来循环对象的属性,并在数组和字符串上使用For/of循环。我无法理解这两个术语。这两者有什么区别呢?
发布于 2021-08-04 09:42:39
Iterable适用于值
值可以是可迭代的,也可以是不可迭代的。它需要实现众所周知的符号@@iterator或@@asyncIterator。实现的方法还必须通过返回迭代器来实现可迭代协议。有了这些功能之后,就可以通过将这些值作为可以迭代的东西来处理,从而实现特殊的交互(因此可以使用“可迭代”的名称)。下面是一些示例:
可迭代性最基本、也可能是最常见的用途是对它们进行迭代。for...of循环将这样做,并从迭代器中获取项,直到没有剩下的项为止。
弦乐:
const str = "hello world";
for (const char of str)
console.log(char);.as-console-wrapper { max-height: 100% !important; }
数组
const arr = ["a", "b", "c", "d"];
for (const item of arr)
console.log(item);.as-console-wrapper { max-height: 100% !important; }
自定义对象
const iterable = {
[Symbol.iterator]() {
let repeat = 0;
return {
next() {
return {
value: 42,
done: repeat++ >= 3
};
}
}
}
}
for (const item of iterable)
console.log(item);.as-console-wrapper { max-height: 100% !important; }
当扩展值时,将使用迭代器,您将得到来自该迭代器的每个值的一些信息。例如,扩展到数组中,[...value]将创建一个具有所有值的数组。扩展到一个函数调用中,fn(...value)将以每个项作为参数调用该函数。
字符串
const str = "hello world";
console.log([...str]); //spread into array
console.log(...str); //spread into function call.as-console-wrapper { max-height: 100% !important; }
数组
const arr = ["a", "b", "c", "d"];
console.log([...arr]); //spread into array
console.log(...arr); //spread into function call.as-console-wrapper { max-height: 100% !important; }
自定义对象
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.as-console-wrapper { max-height: 100% !important; }
这个名字可能有点误导。数组析构总是使用对象的迭代器。这并不意味着它只能用于数组。
字符串
const str = "hello world";
const [first, second] = str;
console.log(first, second);.as-console-wrapper { max-height: 100% !important; }
数组
const arr = ["a", "b", "c", "d"];
const [first, second] = arr;
console.log(first, second);.as-console-wrapper { max-height: 100% !important; }
自定义对象
const iterable = {
[Symbol.iterator]() {
let repeat = 0;
return {
next() {
return {
value: 42,
done: repeat++ >= 3
};
}
}
}
}
const [first, second] = iterable;
console.log(first, second);.as-console-wrapper { max-height: 100% !important; }
枚举用于对象属性。
只能枚举对象属性。没有任何价值。这可以通过使用Object.defineProperty()或Object.defineProperties()或Reflect.defineProperty()或Object.create()进行配置。
不可枚举对象属性
for...in检查所有对象属性时,不要出现。Object.keys()显示。Object.values()中。Object.assign()进行克隆也将跳过不可枚举的属性。很难得到一个详尽的列表,但这传达了这样的想法:不可枚举的属性被排除在属性上的一些“批量”操作之外。
但是,不可枚举的属性仍然可以直接访问.它们不是“隐藏”或“私有”,只是没有出现最常见的机制来抓取所有属性。
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.as-console-wrapper { max-height: 100% !important; }
还有一些机制允许查看不可枚举的属性:例如,Object.getOwnPropertyNames()和Object.getOwnPropertyDescriptors()将能够显示它们。
https://stackoverflow.com/questions/68647965
复制相似问题