[javascript] 함수 내부에서 let을 사용하여 선언 된 일부 변수가 다른 함수에서 사용 가능한 반면 다른 변수가 참조 오류를 발생시키는 이유는 무엇입니까?

함수 내에서 선언 할 때 변수가 왜 그렇게 이상하게 작용하는지 이해할 수 없습니다.

  1. 에서 first함수는 I로 선언 let변수 bc값으로 10 :

    b = c = 10;

    에서 second기능을 내가 보여

    b + ", " + c

    그리고 이것은 보여줍니다 :

    10, 10
  2. 또한 first함수 에서 a10으로 선언 합니다 .

    let a = b = c = 10;

    그러나 second함수에서 오류가 표시됩니다.

    변수를 찾을 수 없습니다 : a

  3. 이제 first함수 에서 d20으로 선언 합니다 .

    var d = 20;

    그러나 second함수 에서 이전과 동일한 오류가 표시되지만 변수는 d다음 과 같습니다.

    변수를 찾을 수 없습니다 : d

예:

function first() {
  let a = b = c = 10;
  var d = 20;
  second();
}

function second() {
  console.log(b + ", " + c); //shows "10, 10"

  try{ console.log(a); }  // Rreference error
  catch(e){ console.error(e.message) }

  try{ console.log(d); } // Reference error
  catch(e){ console.error(e.message) }
}
first()



답변

실제로 말하고 있기 때문입니다.

c = 10;
b = c;
let a = b;

그리고 당신이 생각하는 바가 아닙니다.

let a = 10;
let b = 10;
let c = 10;

체인에 몇 개의 변수를 추가하든 오류를 일으키는 첫 번째 변수 일뿐입니다.

“let”은 변수를 선언 한 블록 (또는 “괄호 안에”를 의미하는 “로컬”으로)의 범위를 지정하기 때문입니다.

“let”없이 변수를 선언하면 변수의 범위가 전체적으로 적용됩니다.

따라서 변수를 설정하는 함수에서 모든 값은 10이됩니다 (중단 점을두면 디버거에서 볼 수 있음). 첫 번째 기능에 a, b, c에 대한 콘솔 로그를 넣으면 모든 것이 좋습니다.

그러나 그 기능을 떠나 자마자 첫 번째 기능은 기술적으로 할당 순서대로 명심해야합니다. 마지막으로 “사라집니다”(다시, 두 번째 함수에서 중단 점을 설정 한 경우 디버거이지만 다른 두 개 (또는 추가 한 많은 수)는 계속 사용할 수 있습니다.

이는 “가져 오기”만이 체인에서 첫 번째 변수 (기술적으로 마지막으로 선언되고 값이 지정됨)에만 적용되기 때문입니다. 나머지는 기술적으로 앞에 “let”이 없습니다. 따라서 기술적으로 전역 적으로 (즉, 전역 객체에) 선언되므로 두 번째 기능에 나타납니다.

“let”키워드를 제거하십시오. 모든 변수를 사용할 수 있습니다.

“var”은 로컬 범위 효과가 비슷하지만 변수가 “호이스트”되는 방식이 다릅니다. 이는 확실히 이해해야하지만 질문과 직접 ​​관련이 없습니다.

(BTW,이 질문은 프로 JS 개발자가 그것을 좋은 것으로 만들 정도로 충분할 것입니다).

키워드, “let”및 “var”을 사용하여 JS에서 변수를 선언하는 방법의 차이점에 대해 시간을 보내십시오.


답변

함수에서 first()변수 b및를 c사용하지 않고 즉석에서 생성된다 var또는let .

let a = b = c = 10; // b and c are created on the fly

와 다른

let a = 10, b = 10, c = 10; // b and c are created using let (note the ,)

그것들은 암시 적 글로벌이됩니다. 그것이 그들이 사용할 수있는 이유입니다second()

에서 문서

선언되지 않은 변수에 값을 할당하면 할당이 실행될 때 암시 적으로 전역 변수 (글로벌 객체의 속성이 됨)로 생성됩니다.

이것을 피하기 위해 "use strict"선언되지 않은 변수를 사용할 때 오류를 제공하는을 사용할 수 있습니다

"use strict"; // <-------------- check this

function first() {
   /*
    * With "use strict" c is not defined.
    * (Neither is b, but since the line will be executed from right to left,
    * the variable c will cause the error and the script will stop)
    * Without, b and c become globals, and then are accessible in other functions
    */
   let a = b = c = 10;
   var d = 20;
   second();
}

function second() {
   console.log(b + ", " + c); //reference error
   console.log(a); //reference error
   console.log(d); //reference error
}

first();


답변

이상하다고 부르기 전에 먼저 몇 가지 기본 사항을 알아 두십시오.

varlet 은 모두 JavaScript에서 변수 선언에 사용됩니다. 예를 들어

var one = 1;
let two = 2;

var또는 을 사용하지 않고 변수를 선언 할 수도 있습니다 let. 예를 들어

three = 3;

이제 위의 접근 방식의 차이가 있다는 것입니다 :

var 기능 범위입니다

let 블록 범위입니다.

var/ let키워드 없이 선언 된 변수의 범위 는 선언 된 위치에 관계없이 전역 이됩니다.

글로벌 변수 는 웹 페이지의 어느 곳에서나 액세스 할 수 있습니다 (글로벌은 실수로 수정 ​​될 수 있으므로 권장되지 않음).

이제 이러한 개념에 따라 문제의 코드를 살펴 보겠습니다.

 function first() {
   let a = b = c = 10;
   /* The above line means:
    let a=10; // Block scope
    b=10; // Global scope
    c=10; // Global scope
    */

   var d = 20; // Function scope
   second();
}

function second() {
   alert(b + ", " + c); // Shows "10, 10" //accessible because of global scope
   alert(a); // Error not accessible because block scope has ended
   alert(d); // Error not accessible because function scope has ended
}


답변

를 사용하는 변수 let키워드를 는 블록 범위 내에서만 사용할 수 있어야하며 외부 함수에서는 사용할 수 없습니다 …

그런 식으로 선언하는 각 변수는 사용하지 않습니다 letvar. 변수 선언에 쉼표가 없습니다.

되는 하지 않는 것이 좋습니다 를 빼고 변수를 선언하는 var키워드. 실수로 기존 전역 변수를 덮어 쓸 수 있습니다. var키워드 없이 선언 된 변수의 범위 는 선언 된 위치에 관계없이 전역이됩니다. 전역 변수는 웹 페이지 어디에서나 액세스 할 수 있습니다.

function first() {
   let a = 10;
   let b = 10;
   let c = 10;
   var d = 20;
   second();
}

function second() {
   console.log(b + ", " + c); //shows "10, 10"
   console.log(a); //reference error
   console.log(d); //reference error
}

first();


답변

이 때문에 사용하지 않는 경우의이다 let또는 var다음 변수는 즉시 선언을 받고, 더 나은 당신은 다음과 같이 선언합니다.

let a = 10;
let b = 10;
let c = 10;


답변

이상한 문제는 JavaScript의 규칙 범위 지정으로 인해 발생합니다.

function first() {
   let a = b = c = 10; // a is in local scope, b and c are in global scope
   var d = 20; // d is in local scope
   second(); // will have access to b and c from the global scope
}

동일한 값 (100)으로 초기화 된 3 개의 로컬 변수 를 선언한다고 가정합니다 . 첫 번째 ()는 다음과 같습니다. 이 경우 second ()는 first ()에 로컬 이기 때문에 변수에 액세스 할 수 없습니다.

function first() {
   let a = 100; // a is in local scope init to 100
   let b = a; // b is in local scope init to a
   let c = b // c is in local scope init to b

   var d = 20; // d is in local scope
   second(); // will not have access a, b, c, or d
}

그러나 전역 변수 를 원하면 first ()는 다음과 같습니다. 이 경우 두 번째는 모든 변수가 전역 범위 에 있기 때문에 모든 변수에 액세스 할 수 있습니다.

function first() {
   a = 100; // a is in global scope
   b = a; // b is in global scope
   c = b // c is in global scope

   d = 20; // d is in global scope
   second(); // will have access to a, b, c, and d from the global scope
}

지역 변수 (일명 선언 된 코드 블록에서 액세스 가능)
코드 블록은 사이에 코드 줄이있는 {}입니다.

  • function () {여기에서 const는 전체 함수에 액세스 할 수 있습니다},
  • for () {여기의 var는 외부 범위에 액세스 할 수 있습니다.
  • 기타

전역 변수 (일명 전역 범위에서 액세스 가능).
이 변수는 전역 객체에 첨부됩니다. 전역 객체는 환경에 따라 다릅니다. 브라우저의 창 개체입니다.

특별 참고 사항 : var, let, const 키워드를 사용하지 않고 JavaScript로 변수를 선언 할 수 있습니다. 이 방법으로 선언 된 변수는 전역 개체에 연결되므로 전역 범위에서 액세스 할 수 있습니다.
a = 100 // is valid and is in global scope

자세한 내용은
https://www.sitepoint.com/demystifying-javascript-variable-scope-hoisting/
https://scotch.io/tutorials/understanding-scope-in-javascript
https : //www.digitalocean .com / community / tutorials / unknown-variables-scope-hoisting-in-javascript


답변

주요 차이점은 범위 지정 규칙입니다. var 키워드로 선언 된 변수는 직접 함수 본문 (따라서 함수 범위)에 범위가 지정되는 반면, 변수는 {} (블록 범위)로 표시되는 즉시 둘러싸는 블록에 범위가 지정됩니다. 그리고 당신이 말할 때

c = 10;
b = c;
let a = b;

c와 b의 수명은 재미 있지만 a는 블록 스팬 뿐이며 참조하여 a에 액세스하려고하면 항상 오류가 표시되지만 c와 b는 전역 적으로 표시되므로 그렇지 않습니다. 체인에 추가하는 변수는 오류를 일으키는 첫 번째 (a) 일뿐입니다. “let”은 변수를 블록의 범위 (또는 “로컬”, “괄호 안에”는 다소 의미가 있기 때문입니다) 때문입니다. “let”없이 변수를 선언하면 전역으로 변수의 범위를 지정합니다. 따라서 변수를 설정하는 함수에서 모든 값은 10이됩니다 (디버거에서이 값을 중단 점). 첫 번째 기능에 a, b, c에 대한 콘솔 로그를 넣으면 모든 것이 잘됩니다. 그러나 해당 기능을 떠나 자마자 첫 번째 기능은 (a) 다시 한 번 명심하십시오.