javascript - 의미 - react let vs const




JavaScript의 변수 범위는 무엇입니까? (18)

올드 스쿨 자바 스크립트

전통적으로 JavaScript에는 두 가지 유형의 범위 만 있습니다.

  1. 글로벌 범위 : 변수는 응용 프로그램의 시작부터 응용 프로그램 전체 (*) 까지 알려져 있습니다.
  2. Functional Scope : 함수 의 시작부터 선언 된 함수에서 변수를 알 수 있습니다 (*).

차이점을 설명하는 답변이 이미 많이 있으므로이 부분에 대해서는 자세히 설명하지 않겠습니다.

최신 자바 스크립트

가장 최근의 자바 스크립트 스펙은 이제 세 번째 범위를 허용합니다.

  1. 블록 범위 : 선언 된 블록에서 변수는 선언 된 순간부터 알 수 있습니다 (**).

블록 범위 변수는 어떻게 작성합니까?

전통적으로 다음과 같이 변수를 생성합니다.

var myVariable = "Some text";

블록 범위 변수는 다음과 같이 작성됩니다.

let myVariable = "Some text";

기능 범위와 블록 범위의 차이점은 무엇입니까?

기능 범위와 블록 범위의 차이를 이해하려면 다음 코드를 고려하십시오.

// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here

function loop(arr) {
    // i IS known here, but undefined
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( var i = 0; i < arr.length; i++ ) {
        // i IS known here, and has a value
        // j IS NOT known here
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( let j = 0; j < arr.length; j++ ) {
        // i IS known here, and has a value
        // j IS known here, and has a value
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here
}

loop([1,2,3,4]);

for( var k = 0; k < arr.length; k++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS NOT known here
};

for( let l = 0; l < arr.length; l++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS known here, and has a value
};

loop([1,2,3,4]);

// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here

여기서 변수 j 는 첫 번째 for 루프에서만 알 수 있지만 앞뒤에서는 알 수 없습니다. 그러나 우리의 변수 i 는 전체 함수에서 알려져 있습니다.

또한, 블록 범위 변수는 게양되지 않기 때문에 선언되기 전에 알려지지 않은 것으로 간주하십시오. 또한 같은 블록 내에서 동일한 블록 범위 변수를 다시 선언 할 수 없습니다. 이것은 블록 스코프 된 변수를 전역 적으로 또는 기능적으로 범위가 지정된 변수보다 오류가 덜 발생하게합니다. 변수는 호이스트되고 다중 선언의 경우 오류를 생성하지 않습니다.

오늘날 블록 스코프 변수를 사용하는 것이 안전합니까?

현재 사용하는 것이 안전한지 여부는 환경에 따라 다릅니다.

  • 서버 측 JavaScript 코드 ( Node.js )를 작성하는 경우 let 문을 안전하게 사용할 수 있습니다.

  • 클라이언트 측 JavaScript 코드를 작성하고 Transizer (Traceur와 같은)를 사용하는 경우 let 문을 안전하게 사용할 수 있지만 코드는 성능면에서 최적이 될 수 있습니다.

  • 클라이언트 측 JavaScript 코드를 작성하고 transpiler를 사용하지 않는 경우 브라우저 지원을 고려해야합니다.

    2016 년 2 월 23 일 현재, 일부 브라우저는 let 지원하지 않거나 일부만 지원합니다.

    • 인터넷 익스플로러 10 이하 (지원 안 함)
    • Firefox 43 이하 (지원 안 함)
    • Safari 9 이하 (지원하지 않음)
    • Opera Mini 8 이하 (지원 안 함)
    • Android 브라우저 4 이하 (지원 안 함)
    • Opera 36 이하 (부분 지원)
    • 초메 51 호 이하 (부분 지원)

브라우저 지원 추적 방법

이 답변을 읽었을 때 let 문을 지원하는 브라우저의 최신 개요는 Can I Use 페이지를 참조하십시오 .

(*) 전역 변수 및 기능적으로 범위가 지정된 변수는 JavaScript 변수가 hoisted 때문에 선언되기 전에 초기화되고 사용될 수 있습니다. 이는 선언이 항상 범위의 맨 위에 있음을 의미합니다.

(**) 블록 범위 변수는 게양되지 않습니다.

자바 스크립트에서 변수의 범위는 무엇입니까? 그들은 함수 밖에서와 같은 내부 범위를 가집니까? 또는 심지어 중요합니까? 또한 전역 적으로 정의 된 변수는 어디에 저장됩니까?


현대 Js, ES6 +, ' const '및 ' let '

다른 주요 언어와 마찬가지로 생성 한 변수마다 블록 범위 지정을 사용해야합니다. var더 이상 사용되지 않습니다 . 이렇게하면 코드를보다 안전하고 관리하기 쉬워집니다.

const95 %의 경우에 사용되어야합니다. 변수 참조 가 변경되지 않도록합니다. 배열, 객체 및 DOM 노드 속성은 변경 될 수 있으며 const 여야합니다.

let 은 재 할당을 기대하는 변수에 사용해야합니다. 여기에는 for 루프가 포함됩니다. 초기화를 넘어 값을 변경 한 경우 let 사용 let .

블록 범위는 변수가 선언 된 대괄호 내에서만 사용할 수 있음을 의미합니다. 이것은 범위 내에서 생성 된 익명 함수를 포함하여 내부 범위까지 확장됩니다.


ES5 이전 :

Javascript의 변수는 처음에는 ES6어휘 적으로 범위가 지정되어 있었습니다 (사전 ). 어휘 적으로 범위가 지정된 용어는 코드를 '보고'변수의 범위를 볼 수 있음을 의미합니다.

var키워드로 선언 된 모든 변수는 함수에 적용됩니다. 그러나 다른 함수가 해당 함수 내에서 선언 된 경우 해당 함수는 외부 함수의 변수에 액세스 할 수 있습니다. 이를 스코프 체인 이라고합니다 . 그것은 다음과 같은 방식으로 작동합니다 :

  1. 함수가 변수 값을 분석하려고하면 먼저 자체 범위를 봅니다. 이것은 함수 본문, 즉 중괄호 {} 사이의 모든 것입니다 ( 이 범위에있는 다른 함수 안에있는 변수 제외 ).
  2. 함수 본문 내부에서 변수를 찾을 수 없으면 체인까지 올라가서 함수가 정의 된 함수의 변수 범위를 봅니다 . 이것은 어휘 범위와 관련이 있습니다.이 함수가 정의 된 코드에서 코드를 볼 수 있으므로 코드를 보는 것만으로 범위 체인을 결정할 수 있습니다.

예:

// global scope
var foo = 'global';
var bar = 'global';
var foobar = 'global';

function outerFunc () {
 // outerFunc scope
 var foo = 'outerFunc';
 var foobar = 'outerFunc';
 innerFunc();
 
 function innerFunc(){
 // innerFunc scope
  var foo = 'innerFunc';
  console.log(foo);
  console.log(bar);
  console.log(foobar);
  }
}

outerFunc();

어떻게 우리가 변수를 로그인을 시도 할 때 발생하는 foo, bar그리고 foobar콘솔에 다음은 :

  1. 우리는 콘솔에 foo를 기록하려고 시도합니다. foo는 함수 innerFunc자체 안에 있습니다. 따라서 foo의 값은 문자열로 해석됩니다 innerFunc.
  2. 우리는 콘솔에 막대를 기록하려고 시도합니다. 막대는 함수 innerFunc자체 안에 없습니다 . 그러므로 스코프 체인올라야합니다 . 먼저 함수 innerFunc가 정의 된 외부 함수를 살펴 봅니다 . 이것은 함수 outerFunc입니다. 의 범위에서 outerFunc우리 문자열을 보유하고있는 변수 줄을 찾을 수 있습니다 'outerFunc'.
  3. foobar는 innerFunc에서 찾을 수 없습니다. .따라서 범위 체인 을 innerFunc 범위 까지 올라야합니다 . 여기에서도 찾을 수 없지만, 우리는 글로벌 범위 (즉, 가장 바깥 쪽 범위)에 또 다른 레벨을 올립니다 . 우리는 문자열 'global'을 포함하는 foobar라는 변수를 찾습니다. 범위 체인을 올라간 후에 변수를 찾지 못하면 JS 엔진은 referenceError를 던집니다 .

ES6 (ES 2015) 세 이상 :

어휘 적 범위와 스코프 체인의 동일한 개념이 여전히 적용됩니다 ES6. 그러나 변수를 선언하는 새로운 방법이 도입되었습니다. 다음과 같은 것들이 있습니다 :

  • let : 블록 범위 변수를 만듭니다.
  • const : 초기화해야하며 재 할당 할 수없는 블록 범위 변수를 만듭니다.

가장 큰 차이점 varlet/ constvar함수 인 반면, 범위 let/ const블록 범위이다. 다음은이를 설명하기위한 예입니다.

let letVar = 'global';
var varVar = 'global';

function foo () {
  
  if (true) {
    // this variable declared with let is scoped to the if block, block scoped
    let letVar = 5;
    // this variable declared with let is scoped to the function block, function scoped
    var varVar = 10;
  }
  
  console.log(letVar);
  console.log(varVar);
}


foo();

위의 예에서 letVar는 with let로 선언 된 변수 가 block scoped 이므로 global 값을 기록합니다 . 변수는 해당 블록 외부에 존재하지 않으므로 변수는 if 블록 외부에서 액세스 할 수 없습니다.


"Javascript 1.7"(Mozilla의 Javascript 확장)에서는 let 문을 사용 하여 블록 범위 변수를 선언 할 수 있습니다.

 var a = 4;
 let (a = 3) {
   alert(a); // 3
 }
 alert(a);   // 4

JS에는 함수 범위 만 있습니다. 범위를 차단하지 마라! 무엇이 너무 감추고 있는지 볼 수 있습니다.

var global_variable = "global_variable";
var hoisting_variable = "global_hoist";

// Global variables printed
console.log("global_scope: - global_variable: " + global_variable);
console.log("global_scope: - hoisting_variable: " + hoisting_variable);

if (true) {
    // The variable block will be global, on true condition.
    var block = "block";
}
console.log("global_scope: - block: " + block);

function local_function() {
    var local_variable = "local_variable";
    console.log("local_scope: - local_variable: " + local_variable);
    console.log("local_scope: - global_variable: " + global_variable);
    console.log("local_scope: - block: " + block);
    // The hoisting_variable is undefined at the moment.
    console.log("local_scope: - hoisting_variable: " + hoisting_variable);

    var hoisting_variable = "local_hoist";
    // The hoisting_variable is now set as a local one.
    console.log("local_scope: - hoisting_variable: " + hoisting_variable);
}

local_function();

// No variable in a separate function is visible into the global scope.
console.log("global_scope: - local_variable: " + local_variable);

JavaScript 코드 (글로벌 코드 또는 함수)의 모든 청크에는 이와 관련된 범위 체인이 있습니다. 이 범위 체인은 해당 코드의 "범위 내에있는"변수를 정의하는 객체 목록 또는 체인입니다. JavaScript가 변수 x ( 변수 해상도 라고하는 프로세스)의 값을 조회해야하는 경우 체인에서 첫 번째 객체를 보면 시작됩니다. 해당 객체에 x 라는 속성이 있으면 해당 속성의 값이 사용됩니다. 첫 번째 객체에 x 라는 속성이 없으면 JavaScript는 체인의 다음 객체로 검색을 계속합니다. 두 번째 객체에 x 라는 속성이 없으면 검색이 다음 객체로 이동합니다. x 가 범위 체인에있는 객체의 속성이 아니면 x 가 해당 코드의 범위에 있지 않고 ReferenceError가 발생합니다. 최상위 JavaScript 코드 (즉, 함수 정의에 포함되지 않은 코드)에서 범위 체인은 전역 객체 인 단일 객체로 구성됩니다. 중첩되지 않은 함수에서 범위 체인은 두 개의 객체로 구성됩니다. 첫 번째는 함수의 매개 변수와 지역 변수를 정의하는 객체이고 두 번째는 전역 객체입니다. 중첩 된 함수에서 범위 체인에는 세 개 이상의 개체가 있습니다. 이 사슬의 사슬이 어떻게 생성되는지 이해하는 것이 중요합니다. 함수가 DEFINED 일 때 유효 범위 체인을 저장합니다. 이 함수가 INVOKED 될 때 로컬 변수를 저장하는 새로운 객체를 생성하고 그 객체를 저장된 범위 체인에 추가하여 해당 함수 호출의 범위를 나타내는 새롭고 긴 체인을 만듭니다. 이것은 외부 함수가 호출 될 때마다 내부 함수가 다시 정의되기 때문에 중첩 된 함수에 대해 더 흥미롭게됩니다. 스코어 체인은 외부 함수의 각 호출마다 다르므로 내부 함수는 정의 될 때마다 미묘하게 다릅니다 . 내부 함수 의 코드 는 외부 함수를 호출 할 때마다 동일하지만 범위와 관련된 체인은 코드가 달라 집니다. 스코프 체인의 이러한 개념은 클로저를 이해하는 데 중요합니다.


Javascript는 범위 체인을 사용하여 주어진 함수의 범위를 설정합니다. 일반적으로 하나의 전역 범위가 있으며 정의 된 각 함수에는 자체 중첩 범위가 있습니다. 다른 함수 내에 정의 된 함수는 외부 함수에 연결된 로컬 범위를가집니다. 범위를 정의하는 것은 항상 소스의 위치입니다.

범위 체인의 요소는 기본적으로 부모 범위에 대한 포인터가있는 Map입니다.

변수를 해결할 때 자바 스크립트는 가장 안쪽 범위에서 시작하여 바깥쪽으로 검색합니다.


나는 내가 할 수있는 최선의 방법이 당신에게 많은 예시를 줄 것이라고 생각합니다. Javascript 프로그래머는 실제로 범위를 얼마나 잘 이해했는지에 따라 순위가 결정됩니다. 때로는 반 직관적 일 수 있습니다.

  1. 전역 범위 변수

    // global scope
    var a = 1;
    
    function one() {
      alert(a); // alerts '1'
    }
    
  2. 로컬 범위

    // global scope
    var a = 1;
    
    function two(a) { // passing (a) makes it local scope
      alert(a); // alerts the given argument, not the global value of '1'
    }
    
    // local scope again
    function three() {
      var a = 3;
      alert(a); // alerts '3'
    }
    
  3. 중급 : 자바 스크립트에서 블록 범위와 같은 것은 존재하지 않습니다 (ES5; ES6에서는 let 소개합니다)

    에이.

    var a = 1;
    
    function four() {
      if (true) {
        var a = 4;
      }
    
      alert(a); // alerts '4', not the global value of '1'
    }
    

    비.

    var a = 1;
    
    function one() {
      if (true) {
        let a = 4;
      }
    
      alert(a); // alerts '1' because the 'let' keyword uses block scoping
    }
    
  4. 중급 : 개체 속성

    var a = 1;
    
    function Five() {
      this.a = 5;
    }
    
    alert(new Five().a); // alerts '5'
    
  5. 고급 기능 : 종료

    var a = 1;
    
    var six = (function() {
      var a = 6;
    
      return function() {
        // JavaScript "closure" means I have access to 'a' in here,
        // because it is defined in the function in which I was defined.
        alert(a); // alerts '6'
      };
    })();
    
  6. 고급 : 프로토 타입 기반 범위 분석

    var a = 1;
    
    function seven() {
      this.a = 7;
    }
    
    // [object].prototype.property loses to
    // [object].property in the lookup chain. For example...
    
    // Won't get reached, because 'a' is set in the constructor above.
    seven.prototype.a = -1;
    
    // Will get reached, even though 'b' is NOT set in the constructor.
    seven.prototype.b = 8;
    
    alert(new seven().a); // alerts '7'
    alert(new seven().b); // alerts '8'
    
  7. 글로벌 + 로컬 : 복잡한 사례

    var x = 5;
    
    (function () {
        console.log(x);
        var x = 10;
        console.log(x); 
    })();
    

    자바 스크립트는 항상 변수 선언 (초기화가 아님)을 범위의 맨 위로 이동시켜 코드가 다음과 동일하게 만들기 때문에 undefined510 대신 10 을 인쇄합니다.

    var x = 5;
    
    (function () {
        var x;
        console.log(x);
        x = 10;
        console.log(x); 
    })();
    
  8. 절 범위 변수 잡기

    var e = 5;
    console.log(e);
    try {
        throw 6;
    } catch (e) {
        console.log(e);
    }
    console.log(e);
    

    그러면 5 , 6 , 5 가 인쇄됩니다. catch 절 안에는 전역 변수와 지역 변수가 그림자로 표시됩니다. 그러나이 특별한 범위는 잡힌 변수에만 해당됩니다. var f; 쓰면 var f; catch 절 내부에서 try-catch 블록 이전이나 이후에 정의한 것과 완전히 동일합니다.


다른 답변에 추가하기 위해 스코프는 선언 된 모든 식별자 (변수)를 조회하는 목록이며 현재 실행중인 코드에 액세스 할 수있는 방법에 대한 엄격한 규칙을 적용합니다. 이 조회는 LHS (왼쪽 측면 참조) 인 변수에 지정하기위한 것이거나 RHS (오른 쪽) 참조 인 값을 검색하기위한 목적 일 수 있습니다. 이러한 룩업은 JavaScript 엔진이 코드를 컴파일하고 실행할 때 내부적으로 수행하는 작업입니다.

그래서이 관점에서 볼 때, 카일 심슨 (Kyle Simpson)의 스코프 및 클로저 전자 서적에서 발견 된 그림이 도움이 될 것이라고 생각합니다.

그의 서적에서 인용 :

이 빌딩은 프로그램의 중첩 스코프 룰 세트를 나타냅니다. 건물의 1 층은 현재 실행중인 범위를 나타냅니다. 건물의 최상위 수준은 글로벌 범위입니다. 현재 층을보고 LHS 및 RHS 참조를 해결하고 찾을 수없는 경우 엘리베이터를 타고 다음 층으로 이동 한 다음 그 다음으로 이동합니다. 최상층 (글로벌 범위)에 도달하면 찾고있는 것을 찾거나 그렇지 않은 것 중 하나를 찾습니다. 그러나 당신은 관계없이 그만해야합니다.

주목할만한 한 가지 언급은 "스코어 조회는 일단 첫 번째 일치를 찾으면 중지됩니다".

이 "범위 수준"개념은 중첩 된 함수에서 조회되는 경우 새로 작성한 범위로 "this"를 변경할 수있는 이유를 설명합니다. 여기에 모든 세부 사항에 들어가는 링크가 있습니다. 자바 스크립트 범위에 대해 알고 싶었던 모든 것


다음은 그 예입니다.

<script>

var globalVariable = 7; //==window.globalVariable

function aGlobal( param ) { //==window.aGlobal(); 
                            //param is only accessible in this function
  var scopedToFunction = {
    //can't be accessed outside of this function

    nested : 3 //accessible by: scopedToFunction.nested
  };

  anotherGlobal = {
    //global because there's no `var`
  }; 

}

</script>

클로저를 조사하고 비공개 멤버 를 만드는 방법을 알아 보겠습니다.


자바 스크립트 스코프에는 두 가지 유형 만 있습니다.

  • 각 var 선언의 범위는 가장 바로 둘러싸는 함수와 연관됩니다
  • var 선언에 포함 함수가없는 경우 전역 범위입니다.

따라서 함수가 아닌 다른 블록은 새 범위를 만들지 않습니다. 이는 for-loops가 외부 범위 변수를 덮어 쓰는 이유를 설명합니다.

var i = 10, v = 10;
for (var i = 0; i < 5; i++) { var v = 5; }
console.log(i, v);
// output 5 5

대신 함수 사용 :

var i = 10, v = 10;
$.each([0, 1, 2, 3, 4], function(i) { var v = 5; });
console.log(i,v);
// output 10 10

첫 번째 예에서는 블록 범위가 없으므로 처음에 선언 된 변수를 덮어 씁니다. 두 번째 예에서는 함수로 인해 새로운 범위가 있으므로 처음에 선언 된 변수는 SHADOWED 였고 덮어 쓰지 않았습니다.

자바 스크립트 범위 지정과 관련하여 알아야 할 거의 모든 사항은 다음과 같습니다.

따라서 JavaScript 스코핑은 실제로는 항상 직관적이지는 않지만 실제로는 매우 간단합니다. 알고 있어야 할 몇 가지 사항은 다음과 같습니다.

  • var 선언은 범위의 맨 위로 끌어 올려집니다. 즉, var 선언이 어디에서 발생하든 관계없이 컴파일러에서는 var 자체가 맨 위에서 발생하는 것처럼됩니다.
  • 동일한 범위 내의 여러 var 선언이 결합됩니다.

그래서이 코드 :

var i = 1;
function abc() {
  i = 2;
  var i = 3;
}
console.log(i);     // outputs 1

다음과 같습니다.

var i = 1;
function abc() {
  var i;     // var declaration moved to the top of the scope
  i = 2;
  i = 3;     // the assignment stays where it is
}
console.log(i);

이것은 직관에 반하는 것처럼 보일 수 있지만 명령형 언어 디자이너의 관점에서 볼 때 의미가 있습니다.


자바 스크립트에 익숙하지 않은 많은 사람들이 언어에서 기본적으로 상속을 사용할 수 있다는 것을 이해하는 데 어려움을 겪고 있으며 그 기능 범위가 유일한 범위입니다. 나는 작년 말에 내가 작성한 미화에 대한 확장을 JSPretty라고했다. 지형지 물 색상은 코드의 범위를 기능하며 항상 해당 범위에서 선언 된 모든 변수에 색상을 연결합니다. 한 스코프의 색상이있는 변수가 다른 범위에서 사용될 때 클로저가 시각적으로 증명됩니다.

다음 위치에서 기능을 사용해보십시오.

데모보기 :

코드보기 :

현재이 기능은 깊이가 16 개의 중첩 기능을 지원하지만 현재는 전역 변수를 채색하지 않습니다.


코드를 실행하십시오. 이것이 범위 지정에 대한 아이디어를 줄 수 있기를 바랍니다.

Name = 'global data';
document.Name = 'current document data';
(function(window,document){
var Name = 'local data';
var myObj = {
    Name: 'object data',
    f: function(){
        alert(this.Name);
    }
};

myObj.newFun = function(){
    alert(this.Name);
}

function testFun(){
    alert("Window Scope : " + window.Name + 
          "\nLocal Scope : " + Name + 
          "\nObject Scope : " + this.Name + 
          "\nCurrent document Scope : " + document.Name
         );
}


testFun.call(myObj);
})(window,document);

Brendan Eich 가 원래 설계 한 JavaScript의 범위 지정 아이디어는 HyperCard 스크립팅 언어 HyperTalk 에서 나왔습니다.

이 언어에서 표시는 인덱스 카드 스택과 유사하게 수행되었습니다. 배경으로 불리는 마스터 카드가있었습니다. 그것은 투명했고 하단 카드로 볼 수 있습니다. 이 기본 카드의 모든 콘텐츠는 그 위에 놓인 카드와 공유되었습니다. 상단에 놓인 각 카드에는 이전 카드보다 우선 순위가 높은 자체 콘텐츠가 있었지만 원하는 경우 이전 카드에 계속 액세스 할 수있었습니다.

이것이 바로 JavaScript 범위 지정 시스템이 설계된 방식입니다. 그것은 단지 다른 이름을 가지고 있습니다. JavaScript의 카드는 실행 컨텍스트 ECMA 로 알려져 있습니다. 이 문맥들 각각은 세 가지 주요 부분을 포함한다. 변수 환경, 어휘 환경 및이 바인딩. 카드 레퍼런스로 되돌아 가면, 어휘 환경은 이전 카드의 모든 내용을 스택에 포함합니다. 현재 컨텍스트는 스택의 맨 위에 있으며 여기에서 선언 된 모든 컨텐트는 변수 환경에 저장됩니다. 변수 환경은 이름 지정 충돌의 경우에 우선합니다.

이 바인딩은 포함하는 객체를 가리 킵니다. 때로는 범위 또는 실행 컨텍스트가 포함 된 개체가 변경되지 않고 변경됩니다. 예를 들어 포함 된 개체가 window 또는 생성자 함수 일 수있는 선언 된 함수에서와 같이.

이러한 실행 컨텍스트는 컨트롤이 전송 될 때마다 만들어집니다. 컨트롤은 코드 실행이 시작될 때 전송되며 주로 코드 실행으로 수행됩니다.

이것이 기술적 인 설명입니다. 실제로는 JavaScript에서이를 기억하는 것이 중요합니다.

  • 범위는 기술적으로 "실행 컨텍스트"입니다.
  • 컨텍스트는 변수가 저장된 환경 스택을 형성합니다.
  • 스택의 상단이 우선 순위를 갖습니다 (하단은 전역 컨텍스트 임)
  • 각 함수는 실행 컨텍스트를 만듭니다 (항상이 바인딩을 새로운 것으로 만드는 것은 아닙니다)

이것을이 페이지의 이전 예제 (5. "Closure") 중 하나에 적용하면 실행 컨텍스트 스택을 따라갈 수 있습니다. 이 예제에서는 스택에 세 가지 컨텍스트가 있습니다. 그것들은 외부 문맥, 즉시 호출 된 함수의 문맥, var 6이 호출하는 문맥, var 6의 내부에서 반환 된 함수의 문맥이 즉시 호출 된 함수에 의해 정의됩니다.

i ) 외부 상황. 그것은 a = 1의 변수 환경을 가지고있다.
ii ) IIFE 컨텍스트에서는 a = 1의 어휘 환경을 가지지 만 스택에서 우선 순위가 높은 a = 6의 변수 환경
iii ) 반환 된 함수 컨텍스트에서 a = 6의 어휘 환경을 가지며이 값은 호출시 경고에서 참조되는 값입니다.


JavaScript에는 두 가지 유형의 범위가 있습니다.

  • 로컬 범위
  • 전체 범위

Below 함수에는 로컬 범위 변수가 carName있습니다. 그리고이 변수는 함수 외부에서 액세스 할 수 없습니다.

function myFunction() {
    var carName = "Volvo";
    alert(carName);
    // code here can use carName
}

Below 클래스에는 전역 범위 변수가 carName있습니다. 이 변수는 클래스의 모든 곳에서 액세스 할 수 있습니다.

class {

    var carName = " Volvo";

    // code here can use carName

    function myFunction() {
        alert(carName);
        // code here can use carName 
    }
}

전역 : 함수 외부에서 선언 된 변수

Local : 함수 내에서 선언 된 변수이며 해당 범위에서만 호출 할 수 있습니다.


EcmaScript5에는 주로 두 가지 범위, 즉 로컬 범위전역 범위가 있지만 EcmaScript6에서는 주로 세 가지 범위, 로컬 범위, 전역 범위 및 블록 범위 라는 새로운 범위가 있습니다.

블록 범위의 예는 다음과 같습니다.

for ( let i = 0; i < 10; i++)
{
 statement1...
statement2...// inside this scope we can access the value of i, if we want to access the value of i outside for loop it will give undefined.
}

내 이해는 세 가지 범위가 있습니다 : 전역 범위, 전역 적으로 사용할 수 있습니다; 블록과 상관없이 전체 기능에서 사용할 수있는 로컬 범위. 블록 범위는 사용 된 블록, 명령문 또는 표현식에서만 사용 가능합니다. 전역 및 로컬 범위는 함수 또는 외부에서 키워드 'var'로 표시되며 블록 범위는 'let'키워드로 표시됩니다.

전역 및 지역 범위 만 있다고 생각하는 사람들에게 JS에서 블록 범위의 뉘앙스를 설명하는 전체 페이지가 Mozilla에있을 이유를 설명하십시오.

let





var