【问题标题】:JavaScript `of` Keyword (for...of loops)JavaScript `of` 关键字(for...of 循环)
【发布时间】: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自己编出来的还是标准化的?

【问题讨论】:

标签: javascript firefox-addon firefox-addon-sdk


【解决方案1】:

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() 迭代 ArraysObjects 的属性值:

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

  1. Chrome 29–37:for...of 循环功能在首选项后面可用。在 chrome://flags 中,激活“启用实验性 JavaScript”条目。
  2. 在 Firefox 51 之前,使用带有 const 关键字的 for...of 循环构造会引发 SyntaxError(“在 const 声明中缺少 =”)。

【讨论】:

  • 非常有用的答案,我不知道它登陆了FF13
【解决方案2】:

这是 EcmaScript 6 的一项功能,并非所有现代浏览器都支持或稳定。您需要等待它稳定下来,或者您可以使用像 Traceur 这样的转译器,它将您的 ES6 代码转换为 ES5。

【讨论】:

  • “不稳定”是什么意思?另外,转码器是另外一回事,也许您正在寻找单词 transpiler。
  • 他可以使用var tab in tabs 来支持 pre-es6 吗?
  • 所有浏览器都支持使用var tab in tabs 或换句话说for...in 结构。您可以安全使用。 “不稳定”是指在某些浏览器或某些浏览器的某些版本中添加了该功能,但现在相信它的支持可能不是一个好主意。
猜你喜欢
  • 1970-01-01
  • 2020-07-10
  • 2018-11-14
  • 2015-09-04
  • 2018-01-20
  • 2018-11-21
  • 2020-09-19
  • 2020-01-04
相关资源
最近更新 更多