Mah*_*ash 10 javascript iterable enumerable for-in-loop for-of-loop
我在研究 For/in 和 For/of 循环时遇到术语 Iterable 和 Enumerable。对象应该是可枚举的,我们必须使用 For/in 循环来循环对象的属性,并使用 For/of 来循环数组和字符串。我无法理解这两个术语。这两者有什么区别?
Utm*_*tor 11
有几件事是与众不同的。
\n关于可迭代的一些知识:
\n关于枚举的一些信息:
\nenumerable: true- 默认情况下适用于所有 props];更深入一点:
\n\n\n迭代器是附加到数组的另一个对象,它告诉其他函数如何访问其中的所有不同值。\n有数组、字符串、NodeList、Sets、Map,它们有内置迭代器,但对象没有没有它。
\n
默认情况下该对象是不可迭代的,但您可以实现它。
\n所以你可以使用
\nfor .. of用于[array, Map, Set, String]迭代值;for .. in让数组迭代一个键;for .. in让对象枚举其(对象)属性;请查看此处的示例或使用提供的沙箱链接。\n同一示例的沙箱链接。
\nlet arr = [\'value1\', \'value2\', \'value3\'];\n\nlet obj = {\n propName1: \'propValue1\',\n propName2: \'propValue2\',\n propName3: \'propValue3\'\n};\n\nconsole.log(\'=====================WORKING WITH ARRAYS===================\');\nconsole.log(\'For Of \')\nfor (const value of arr) {\n console.log(\'value: \', value);\n}\n\nconsole.log(\'For In\');\nfor (const key in arr) {\n console.log(\'key: \', key, \' value: \', arr[key]);\n}\n\nconsole.log(\'=====================WORKING WITH OBJECTS===================\');\nconsole.log(\'For In:\');\nfor (const prop in obj) {\n console.log(\'prop: \', prop, \'value: \', obj[prop]);\n}\n\nObject.defineProperty(obj, "definedPropEnFalse", {\n value: \'value of definedPropEnFalse\',\n enumerable: false,\n});\n\nObject.defineProperty(obj, "definedPropEnTrue", {\n value: \'value of definedPropEnTrue\',\n enumerable: true,\n});\n\nconsole.log(\'For In for Objects with enumerables:\');\nfor (const prop in obj) {\n console.log(\'prop: \', prop, \'value: \', obj[prop]);\n}\n\nconsole.log(\'For In for Objects with Object.keys and forEach:\');\nObject.keys(obj).forEach(e => console.log(`key=${e} value=${obj[e]}`));\n\n\nconsole.log(\'=====================WORKING WITH STRINGS===================\');\nlet str = "Go Over A String"\nconsole.log(\'Using For Of for String:\');\nfor (const char of str) {\n console.log(char);\n}\n\n\nconsole.log(\'=====================WORKING WITH Sets===================\');\nconsole.log("Looping over a Set");\nlet testSet = new Set();\ntestSet.add(\'Hello\');\ntestSet.add(\'Hope\');\ntestSet.add(\'You are getting it xD\');\n\nfor (const setItem of testSet) {\n console.log(setItem);\n}\n\n\nconsole.log(\'=====================WORKING WITH Maps===================\');\nconsole.log(\'Iterate over Map using For of\')\nvar myMap = new Map();\nmyMap.set("0", "foo");\nmyMap.set(1, "bar");\nmyMap.set({}, "baz");\n\nfor (const [key, value] of myMap.entries()) {\n console.log(key, value);\n}Run Code Online (Sandbox Code Playgroud)\r\n助记符:
\n另一个助记符:
\nfor..in..keys===外键=== 用于for...in键;for...of对于价值观。in给你索引。
摘自这篇文章的评论
\n如果一个对象从技术上来说是一个数组,但代表了某个东西的集合(列表、集合),那么for..of循环它是一个很好的语法。
值可以是可迭代的,也可以是不可迭代的。它需要实现众所周知的符号@@iterator或@@asyncIterator。实现的方法还必须通过返回迭代器来满足可迭代协议。有了这些,就可以通过将这些值视为可以迭代的东西来与这些值进行特殊的交互(因此称为“可迭代”)。这里有些例子:
for...of可迭代对象最基本也可能最常见的用途是迭代它们。该for...of循环将执行此操作并从迭代器中获取项目,直到没有剩余为止。
const str = "hello world";
for (const char of str)
console.log(char);Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }Run Code Online (Sandbox Code Playgroud)
const arr = ["a", "b", "c", "d"];
for (const item of arr)
console.log(item);Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }Run Code Online (Sandbox Code Playgroud)
const iterable = {
[Symbol.iterator]() {
let repeat = 0;
return {
next() {
return {
value: 42,
done: repeat++ >= 3
};
}
}
}
}
for (const item of iterable)
console.log(item);Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }Run Code Online (Sandbox Code Playgroud)
...当传播值时,会使用迭代器,并且您会为来自该迭代器的每个值获得一些东西。例如,扩展到数组中将[...value]创建一个包含所有值的数组。传播到函数调用中fn(...value)将以每个项目作为参数来调用该函数。
const str = "hello world";
console.log([...str]); //spread into array
console.log(...str); //spread into function callRun Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }Run Code Online (Sandbox Code Playgroud)
const arr = ["a", "b", "c", "d"];
console.log([...arr]); //spread into array
console.log(...arr); //spread into function callRun Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }Run Code Online (Sandbox Code Playgroud)
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 callRun Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }Run Code Online (Sandbox Code Playgroud)
这个名字可能有点误导。数组解构总是使用对象的迭代器。这并不意味着它只能用于数组。
const str = "hello world";
const [first, second] = str;
console.log(first, second);Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }Run Code Online (Sandbox Code Playgroud)
const arr = ["a", "b", "c", "d"];
const [first, second] = arr;
console.log(first, second);Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }Run Code Online (Sandbox Code Playgroud)
const iterable = {
[Symbol.iterator]() {
let repeat = 0;
return {
next() {
return {
value: 42,
done: repeat++ >= 3
};
}
}
}
}
const [first, second] = iterable;
console.log(first, second);Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }Run Code Online (Sandbox Code Playgroud)
只有对象属性可以是可枚举的。没有任何价值。这可以通过使用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); // 2Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; }Run Code Online (Sandbox Code Playgroud)
还有一些机制允许查看不可枚举的属性:Object.getOwnPropertyNames()例如Object.getOwnPropertyDescriptors()能够显示它们。
| 归档时间: |
|
| 查看次数: |
4689 次 |
| 最近记录: |