JavaScript `of` 关键字(for...of 循环)
Posted
技术标签:
【中文标题】JavaScript `of` 关键字(for...of 循环)【英文标题】:JavaScript `of` Keyword (for...of loops) 【发布时间】:2014-12-18 23:30:52 【问题描述】:我刚刚发现 in Firefox SDK javascript (on MDN) 使用了一个我以前从未见过的关键字:
var tabs = require('sdk/tabs');
for (let tab of tabs)
console.log(tab.title);
of
关键字是Mozilla自己编出来的还是标准化的?
【问题讨论】:
ES6 的一部分。谷歌搜索“for of loop ES6”应该会出现一些东西。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 【参考方案1】:这是 EcmaScript 6 的一项功能,并非所有现代浏览器都稳定或支持。您需要等待它稳定下来,或者您可以使用像 Traceur 这样的转译器,它将您的 ES6 代码转换为 ES5。
【讨论】:
“不稳定”是什么意思?另外,转码器是另外一回事,也许您正在寻找 transpiler 这个词。 他可以使用var tab in tabs
来支持 pre-es6 吗?
所有浏览器都支持使用var tab in tabs
或换句话说for...in 结构。您可以安全使用。 “不稳定”是指在某些浏览器或某些浏览器的某些版本中添加了该功能,但现在相信它的支持可能不是一个好主意。【参考方案2】:
for...of
循环遍历属性 values,是 added to the JavaScript specification in ECMAScript 2015 的一项功能。
鉴于此问题的上下文是 Firefox 插件,问题不在于它何时或是否在其他浏览器中可用。问题是当这个ECMAScript 2015 feature was added to Firefox 以及使用它导致的向后兼容性的任何限制时。
它已在 Firefox 13 中添加到 Firefox。因此,使用它会导致将您的附加组件限制为 Firefox 13+。鉴于截至 2014 年 10 月的当前版本是 Firefox 33.0,并且在 Firefox 13 和现在之间已经有多个 ESR 版本,使用for...of
循环可能不会显着减少能够使用您的添加的人数-在。您正在使用的某些其他功能可能会将您的插件限制为更新的版本。
使用for...of
与Array.prototype.forEach() 不同,for...of
循环不仅限于数组,还将迭代其他类型的iterable objects,其中包括大量不同类型的对象。
有时让人们感到困惑的一件事是for...of
迭代属性values,而不是属性键。根据您的操作,这可能非常方便,也可以使 for...of
循环不合适。
示例:for..of
迭代 NodeList
const listItems = document.querySelectorAll('li');
for (let item of listItems)
console.log('item text:', item.textContent); // "first", "second", "third", "fourth"
<ol>
<li>first</li>
<li>second</li>
<li>third</li>
<li>fourth</li>
</ol>
普通对象通常不是iterable(不能使用for...of
)
尝试在普通对象上使用for...of
会引发错误。
const obj = first: 3, second: 5, third: 7, fourth: "hello" ;
// with Object.keys()
for (let value of obj) //This is an error. obj is not iterable
console.log('value:', value);
其他迭代 Object 属性值的方法
Array.prototype.forEach()
如果您正在寻找其他方法来执行类似任务,MDN shows examples 使用 Array.prototype.forEach() 迭代 Arrays 和 Objects 的属性值:
forEach
直接覆盖从 Object.values()
获得的 Object 值:
const obj = first: 3, second: 5, third: 7, fourth: "hello" ;
// with Object.keys()
Object.values(obj).forEach(function (value)
console.log('value:', value); // logs "3", "5", "7", "hello"
);
forEach
通过从 Object.keys()
获得的 Object 的键:
const obj = first: 3, second: 5, third: 7, fourth: "hello" ;
// with Object.keys()
Object.keys(obj).forEach(function (key)
//obj[key] is the property value
console.log('key:', key); // logs "first", "second", "third", "fourth"
console.log('value:', obj[key]); // logs "3", "5", "7", "hello"
);
forEach
覆盖数组的值:
const arr = [ 3, 5, 7 ];
arr.forEach(function (value, index)
console.log('value:', value); // logs "3", "5", "7"
console.log('index:', index); // logs "0", "1", "2"
);
for..in
使用for..in
循环的主要缺点是它会迭代对象的enumerable properties,这将包括对象原型上的属性。这可能会导致意外错误。因此,使用Object.prototype.hasOwnProperty()
或其他方法测试循环的键值是否是对象自己的值总是一个好主意,除非您知道要遍历不是的可枚举属性对象自己的属性(您很少想要)。
虽然这不是绝对必要的,但最好使用Object.prototype.hasOwnProperty()
的已知良好副本,因为任何对象都可以有意或无意地定义自己的hasOwnProperty
。
const obj = first: 3, second: 5, third: 7, fourth: "hello" ;
// with for..in
for (let key in obj)
if (Object.prototype.hasOwnProperty.call(obj, key))
//obj[key] is the property value
console.log('key:', key); // logs "first", "second", "third", "fourth"
console.log('value:', obj[key]); // logs "3", "5", "7", "hello"
浏览器兼容性:
如果您打算将您的插件移植到其他浏览器,或在网页中使用for...of
,那么您应该知道何时将该功能添加到各种浏览器。从Browser Compatibility table on MDN 可以看出,主要问题是 Internet Explorer 不支持它。
这是截至 2018 年 3 月 11 日的compatibility table from MDN:
-
Chrome 29–37:
for...of
循环功能在首选项后面可用。在 chrome://flags 中,激活“启用实验性 JavaScript”条目。
在 Firefox 51 之前,使用带有 const
关键字的 for...of
循环构造会引发 SyntaxError(“在 const 声明中缺少 =”)。
【讨论】:
非常有用的答案,我不知道它登陆了FF13以上是关于JavaScript `of` 关键字(for...of 循环)的主要内容,如果未能解决你的问题,请参考以下文章
Javascript 和 Typescript:使用 for..of 对对象进行迭代
JavaScript中for in,for, for of,forEach之间的区别
我可以在 Javascript for...in 和 for...of 循环中使用 continue 和 break 吗?