Javascript 表达式 `["Java", "Python","Javascript"][Symbol.iterator]().next().value` 的计算结果为给定数组的第一个值

Javascript expression `["Java", "Python","Javascript"][Symbol.iterator]().next().value` evaluates to first value of a given array

我在面试中被要求在不使用索引和任何辅助函数的情况下获取数组的第一个值。 然后面试官给了我下面的解决方案,但无法确切地弄清楚如何?

const firstValue = ["Java", "Python","Javascript"][Symbol.iterator]().next().value;

console.log('First Value: ', firstValue);

如果有人能提供更多见解,将会有所帮助和感激。 谢谢!

这是概要:

  • 数组是 可迭代的 ,这意味着它们有一个方法可以通过 属性 以符号 Symbol.iterator 命名,其行为符合规范所述.
  • 当您调用该方法时,它 returns 一个迭代器。
  • 迭代器有一个 next 方法用于从迭代器中获取 "next" 结果:第一次调用 returns 第一个结果,第二次调用 returns第二个结果等
  • 结果是具有布尔值 done 属性 和 value 属性 的对象,具有该迭代的实际值。 (从技术上讲,两者都是可选的:done 默认为 falsevalue 默认为 undefined。但是原生 JavaScript 对象提供的迭代器具有这两个属性都明确。)

下面是该语句执行上述操作的方式:

//                                +----------------------------------------------- create the array
//                                |                       +----------------------- get its `Symbol.iterator` method
//                                |                       |         +------------- call it
//                                |                       |         |   +--------- call the `next` method of the iterator to get the first result object
//                                |                       |         |   |      +-- get its `value` property
//                                |                       |         |   |      |
//                                |                       |         |   |      |
//                                |                       |         |   |      |
//                                |                       |         |   |      |
//                                |                       |         |   |      |
//                                |                       |         |   |      |
//                 \vvvvvvvvvvvvvvvvvvvvvvvvvvvvv/\vvvvvvvvvvvvvvv/\/ \vvvv/ \vvv/
const firstValue = ["Java", "Python","Javascript"][Symbol.iterator]().next().value;

或者更清楚:

// Create the array
const array = ["Java", "Python","Javascript"];
// Get its `Symbol.iterator` method
const iteratorMethod = array[Symbol.iterator];
// Call it
const iterator = iteratorMethod.call(array);
// Call the `next` method of the iterator to get the first result object
const resultObject = iterator.next();
// Get its `value` property
const firstValue = resultObject.value;

console.log(firstValue); // "Java"

[Symbol.iterator] 是一个特殊的 属性,它使 JavaScript 中的任何对象成为 Iterable.因此,在一个 Iterable 对象的数组中,此 属性 存在。

这个属性的作用是return一个Iterator对象有next() 方法。使用迭代器 returned,您可以遍历数组或可迭代对象中的数据。

您还可以创建一个自定义的 Iterable 对象,您可以通过调用其 [Sysmbol.iterator] 方法从中获取 Iterator。这种语法 [] 是 ES6 的新语法,您可以在其中使用任何 Symbol 作为 class 中方法的名称,这被称为计算 属性.

在下面的代码片段中,您可以看到如何使用 [Symbol.iterator] 作为方法名称来创建我自己的可迭代对象。这是一个非常简单的示例,演示了 [Symbol.iterator] 的用法还有其他方法可以做到这一点:

class CustomIterable{

   constructor(start, stop){
      this.start = start;
      this.stop = stop;
   }
   //This property makes this an Iterable
   [Symbol.iterator](){
    return this;
   }
   //This makes this an Iterator also
   next(){
    return this.start !== this.stop ? {value: this.start++, done: false} 
                                    : {value: this.stop, done: true};
   }
 
}

const cutomIterable = new CustomIterable(0, 11);
console.log(cutomIterable[Symbol.iterator]().next().value);
//This object can be a target of the for..of loop
for( let val of cutomIterable){
  console.log(val);
}