Open FrankKai opened 4 years ago
参考资料: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
一直以为of和in在js中是同一类东西。 of不能单独使用;可以与for组合成for...of,for await...of;还有一个Array.of()方法。 但其实in在js中是in operator。可以单独使用;也可以与for组合成for..in。
of篇
in篇
in和of最直观的区别
实践中遇到的使用场景
[mp: 13.914736, lp: c, Oq: 0, size: c]
通过of迭代如何返回?of篇
for...of
for...of语句会基于iterable(可迭代,可遍历) objects创建一个循环迭代。
iterable objects包括哪些?built-in String, Array, array-like objects(arguments,NodeList), TypedArray, Map, Set, 以及用户自定义的iterable。
for...of调用一个自定义的迭代hook(钩子),这个hook主要会对对象的不同属性值做区分,从而对不同属性值做处理。
object是不可迭代的,需要通过Object.entries()将对象iterable化
for(const [key, value] of Object.entries(obj))
使用例子
遍历数组
这里也可以是
let value of iterable
,取决于我们会不会对value重新赋值(reassign)。遍历其他
<p class="read"></p> <p class="read"></p>
其中Map数据类型可以再对value做一次解构,
for ( const [key, value] of iterable ){} // ['foo', 1]->[key, value]
。关闭iterator
for-await...of
高难度操作暂不涉猎
Array.of()
Array.of(element0[, element1[, ...[, elementN]]])
elementN是生成数组的组成元素。返回一个新的Array实例。Array.of(7); // [7] Array(7); // array of 7 empty slots, 数组元素不是undefined,而且length为7
Array.of(1, 2, 3); // [1, 2, 3] Array(1, 2, 3); // [1, 2, 3]
in篇
单独使用in
prop in object
new String('green'); 'green' // 'length' in 前者true,后者false
。var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];0 in trees;//returns true 3 in trees;// returns true 6 in trees;// returns false
delete mycar.make;delete trees[1]
,数组某一项被删除后为empty,用in检测返回false。['foo', 'bar', 'baz']
返回, 1 in ['foo', empty, 'baz'],前者返回true,后者返回false。delete obj.foo
和obj.foo=undefined
不同,delete会把属性key-value直接删除;delete arr[1]
与arr[1]=undefined
也不一样,delete会把arr[1]置为empty。'toString' in {}; // returns true, toString是继承了Object上的__proto__的方法。
for...in
var obj = {a: 1, b: 2, c: 3}; for (const prop in obj) {console.log(prop)// a,b,c}
in与hasOwnProperty的区别
console.log("in check", "name" in foo); // true console.log("in prototype check", "age" in foo); // true
console.log("hasOwnProperty check", foo.hasOwnProperty("name")); // true console.log("hasOwnProperty prototype check", foo.hasOwnProperty("age")); // true
of需要借助Object.entries()
实践中遇到的使用场景
如何检测一个空对象?
解法一:Object.prototype.toString.call和JSON.stringify。
解法二:Object.keys(),Object.values() length===0
解法三:错误解法for...of,正确解法for...in。 错误解法:
正确解法:
为什么? of只能遍历iterable的对象,包括String,TypedArray,Map,Set,arguments,DOM collection 等等。 如果是一个最最普通的对象"const obj = {}"呢?不能。会抛出异常
obj is not iterable
。 引申:如何才能让它iterable呢?可以使用Object.defineProperty吗? 不行。 仍然会抛出obj is not iterable
。况且都是空对象了,prop1属性根本就不存在的好吗。即使prop1属性存在,使用for...of仍然无法遍历。
如何遍历普通对象{foo: 1, bar: 2}?
由于普通的object直接用of是不可迭代的,因此需要通过Object.entries将其迭代化。 或者通过in进行迭代。
通过in和of取到的单个条目,修改这个单个条目,会影响原对象吗?
不会影响。
修改in的条目:不会影响。
修改of的条目:不会影响。
还是需要通过obj[xxx]去修改原对象,用of修改更合适
普通数组['abc', 'dd', 'foo']通过of迭代如何返回?
特殊数组
[mp: 13.914736, lp: c, Oq: 0, size: c]
通过of迭代如何返回?这个是一个特殊的数组,不能直接访问,需要在特定情况下访问。 这样的特殊数组本质上也是继承自Object,因此可以通过Object.entries遍历。