2017-12-30 42 views
0

for 루프 내에 다른 함수가있는 간단한 함수가 있습니다. main 함수는 sub 함수를 반환합니다. main 함수가 호출되면 루프가 실행되지만 아직 호출되지 않았으므로 하위 함수는 아직 실행되지 않습니다. 루프가 실행 된 후 sub 함수가 호출되므로 i 값은 배열의 마지막 요소 값을 가리 킵니다. 이 배열의 각 값에 대한 새로운 바인딩을 원한다면 어떻게 수정합니까?자바 스크립트에서 루프 내부 클로저

function getName() { 
 
    const arr = ['a', 'b', 'c', 'd']; 
 
    for (let i = 0; i < arr.length; i++) { 
 
     function sendName() { 
 
      alert(arr[i]); 
 
     } 
 
    } 
 
    return sendName; 
 
} 
 
var receiveName = getName(); 
 
receiveName();

+1

당신이 묻는 것은 말이되지 않습니다. 나중에 호출 할 함수를 반환하는'getName()'을 한 번 호출합니다. 어떻게 그 단일 호출은 "각각의 값에 대한 새로운 바인딩"을 가질 수 있습니까? 그것은'getName()'의 단일 결과입니다. 어쩌면 일련의 함수를 반환 할 수 있을까요? –

+0

코드가 엄격 모드에서도 작동하지 않습니다. [함수는 블록 범위입니다] (https://stackoverflow.com/a/31461615/1048572). 반환하는'sendName' 변수는 존재하지 않습니다. 큰 문제의 일부인 :'getName()'은 하나의 함수 만 반환합니다. 다른 인덱스를 가리키는 다른 함수를 어떻게 호출 할 것인가? (루프에서 'let'을 사용하기 때문에 실제로 작동하는 부분이다.) – Bergi

+0

[루프 내부의 JavaScript 클로저 - 가능한 간단한 예제] (https : // stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) –

답변

1

대신 익명의 래퍼 사용할 수 있습니다 더 자세한 설명을 제공 할 때까지 주석에 언급 된 다른 사람들이, 이러한 구현은 거의 의미로, 또한

function getName() { 
    const arr = ['a', 'b', 'c', 'd']; 
    for (let i = 0; i < arr.length; i++) { 
     (function() { 
      alert(arr[i]); 
     })(i); 
    } 
} 
getName(); 

을 왜 당신은 그것을 필요로하는지에 관해서. 아마도 귀하의 요구 사항에 맞는보다 세련된 솔루션이 있어야합니다.

+1

여기에 IIFE를 사용할 점은 없습니다. 특히 어쨌든 즉시 경고 할 경우. – Bergi

+0

그게 효과가있어! – Kshri

+1

@Bergi 우리는 저자의 요점과 기능 구현을 정확히 모릅니다. – Oleksandr

2

당신은 당신이 원하는 것을 달성하기 위해 bind 기능을 사용할 수 있습니다 :

function sendName(name) { 
 
    alert(name); 
 
} 
 

 
function getNames() { 
 
    const arr = [ 'a','b','c','d' ]; 
 
    let sendNames = []; //Dunno what you want to do with this functions so let's store them in an array 
 
    for(let i = 0; i < arr.length; i++) { 
 
    sendNames.push(sendName.bind(this, arr[i])); // this - context, later arguments 
 
    } 
 
\t return sendNames; 
 
} 
 
var receivedNames = getNames(); 
 
receivedNames[1](); //b 
 
receivedNames[3](); //d

+0

내 대답에 부정적인 표를 추가 할 때 의견에 피드백을 추가하여 잘못된 점을 이해할 수 있도록하십시오. – Oskar

+0

왜 그렇게 복잡합니까? OP가 함수를 생성하는 코드는 이미 작동하지만 배열의 비트는 작동하지 않습니다. – Bergi

+1

@Bergi 다른 경우에는 자체 호출 함수로'alert (arr [i]) '를 호출 할 수 있습니다. 질문의 본질은 호출을 나중에 지연시키는 방법입니다. – Oskar

1

당신은 다른 기능을 저장하는 배열을 사용할 수 있습니다. 이 예제에서는 N에 따라 다른 문자를 반환합니다.

function getName() { 
 
const arr=['a','b','c','d']; 
 
    let a = []; 
 
\t for(let i = 0;i<arr.length;i++) { 
 
\t \t a.push(function() { 
 
\t \t \t alert(arr[i]); 
 
\t \t }); 
 
\t } 
 
\t return a; 
 
} 
 
var receiveName=getName(); 
 
let N = 0; // returns a 
 
receiveName[N](); 
 
console.log(receiveName);

은 우리가 이미 let를 사용하는 같은 기능의 범위에 alert(a[i])을 포장 할 지점이 없다고 생각

+1

'let i' 선언을 루프 헤더에 보관했다면, 임시 변수'l'은 필요 없습니다. – Bergi

+0

예 답변을 수정했습니다. –

1

을하는 데 도움이 블록 범위를 제공 바랍니다.

우리는 다음 함수를 사용할 수 있으며 필요한 결과를 출력 할 수 있습니다. 그 한 번만 예라고하기 때문에

function getName() { 
    const arr = ['a', 'b', 'c', 'd']; 
    for (let i = 0; i < arr.length; i++) { 
      alert(arr[i]); 
    } 
} 
getName(); 
0

이 도

불구하고 ...입니다
function sendName(){ 
alert(arr[i]); 
    } 

sendName이 할당 된 값을 네 번 변화하고 있지만, 따라서 그것은 단지 경고되고, 한 번만 호출됩니다 " d "는 d가 마지막으로 할당 된 값이기 때문입니다. "a", "b", "c", "d"를 경고하려면 루프 내부에서 함수를 호출하십시오.