Javascript表达式`[“ Java”,“ Python”,“ Javascript”] [Symbol.iterator]()。next()。value`求值为给定数组的第一个值

时间:2019-09-17 05:57:46

标签: javascript arrays iterator symbols

有人在采访中要求我不使用索引和任何辅助函数来获取数组的第一个值。 然后,面试官给我下面的解决方案,该解决方案有效,但无法确切说明如何解决?

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

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

如果任何人都可以提供更多的见解,将会有所帮助并受到赞赏。 谢谢!

2 个答案:

答案 0 :(得分:3)

以下是摘要:

  • 数组是可可迭代的,这意味着它们具有通过符号Symbol.iterator命名的属性可用的方法,该属性的行为符合规范的规定。
  • 调用该方法时,它将返回一个迭代器。
  • 迭代器具有一个next方法,可用于从迭代器获取“下一个”结果:第一个调用返回第一个结果,第二个调用返回第二个结果,依此类推。
  • 结果是对象具有布尔done属性和value属性,并具有该迭代的实际值。 (从技术上讲,两者都是可选的:done默认为falsevalue默认为undefined。但是本机JavaScript对象提供的迭代器明确具有这两个属性。)< / em>

因此,该语句可以完成上述操作:

//                                +----------------------------------------------- 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"

答案 1 :(得分:2)

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

此属性的作用是返回具有next()方法的 Iterator 对象。使用返回的迭代器,您可以遍历数组或可迭代对象中的数据。

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

在下面的代码片段中,您可以看到如何使用[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);
}