2016-12-30 1 views
2

그래서 배열에서 값을 반환해야하는 생성기 함수가 있지만 배열에 생성기의 출력을 소비하는 동일한 루프가 채워지는 상황이 있습니다.반복 중에 기본 컬렉션에 추가되는 경우 배열 반복기의 동작이 정의됩니까?

특정 시나리오는 자동 디코딩 된 문자가 암호 키의 끝에 추가되는 autokey 암호에 대한 키 시퀀스를 반환하는 생성기입니다. 내 구현은 작동하지만 작동 여부가 확실하지 않거나 정의되지 않은 동작의 예가 부탁하는 경우 확실하지 않습니다.

기본적으로 아래 코드는 항상 "a", "b", "c", "d", "e"를 인쇄하거나 "a", "b" "c", "undefined", "undefined"? 반복되는 컬렉션을 수정하는 것에 대해서는 항상 염려 스럽습니다.

let a = ["a", "b", "c"]; 
let iter = function*() { yield* a; }(); 
console.log(iter.next().value); // "a" 
console.log(iter.next().value); // "b" 
a.push("d"); 
a.push("e"); 
console.log(iter.next().value); // "c" 
console.log(iter.next().value); // "d" - but is this guaranteed? 
console.log(iter.next().value); // "e" - or is it? 

편집는 : 카일 심슨에 의해, "반복자는"더 정확하게 넘어 ES6 &에 따라 질문

+0

제너레이터 시작 부분에 복사본을 작성한 다음 사본에 'yield *'를 만들어야한다고 생각합니다. – user949300

+1

예, ES6은 모든 콜렉션이 변이를 처리 할 수 ​​있도록'@@ iterator()'의 동작을 지정합니다. – Bergi

답변

2

의 실제 고기를 반영하는 "발전기"에 대해 이야기에서 제목을 변경 피. 103, yield *반복 가능이며이고 "iterable의 반복자를 호출합니다". 따라서 당신은 실제로 반복 가능 동작이 아니라 생성기 동작을 요구합니다.

기본 배열이 수정되었을 때 배열의 반복자가 반응하는 방식에 대한 공식 사양을 찾는 데 어려움이 있었지만 그러한 기본 기능이 올바르게 구현되었다고 가정해야합니다. 예를 들어 실험마다 새로운 배열 요소가 포함됩니다 iterable에서. 물론 IE6를 사용하고 있지 않는 한. :-)

따라서 발전기에 원래 요소 인 a[] 만 포함하려면 복사본을 만들어야합니다. 예 :

let iter = function*(a) { 
    let copy = Array.from(a); 
    yield * copy; 
} 
+0

용어에 대한 수정 주셔서 감사합니다! 당신 말이 맞아요, 제 질문은 반복적 인 행동에 관한 것이 었습니다. 실제로 원하는 결과를 얻고 있습니다. (새로 추가 된 요소를 포함하여 모든 요소를 ​​얻을 수 있기를 바랍니다.) 그 동작이 사양에 의해 잘 정의되었는지 여부에 대해서는 궁금했습니다. Bergi의 코멘트에서, 그리고 실제로 옳은 일 (Array iterators, generator behavior가 아닌)을 실제로 찾았으므로 % ArrayIteratorPrototype % .next()가 현재 길이 (http : //www.ecma-international. org/ecma-262/6.0/# sec- % arrayiteratorprototype % .next) – PMV