[javascript] 어휘 범위는 무엇입니까?

어휘 범위 지정에 대한 간략한 소개는 무엇입니까?



답변

예를 통해 이해합니다. 🙂

먼저 C와 같은 구문으로 어휘 범위 ( 정적 범위 라고도 함 ) :

void fun()
{
    int x = 5;

    void fun2()
    {
        printf("%d", x);
    }
}

모든 내부 레벨은 외부 레벨에 액세스 할 수 있습니다.

C와 유사한 구문 으로 Lisp 의 첫 번째 구현에서 사용되는 동적 범위 라는 또 다른 방법이 있습니다 .

void fun()
{
    printf("%d", x);
}

void dummy1()
{
    int x = 5;

    fun();
}

void dummy2()
{
    int x = 10;

    fun();
}

여기에 fun액세스하거나 할 수 x있는 dummy1하거나 dummy2, 또는 x호출하는 것이 어떤 함수 funx그 안에 선언은.

dummy1();

5를 인쇄합니다

dummy2();

10을 인쇄합니다.

첫 번째는 컴파일 타임에 추론 할 수 있기 때문에 정적이라고하고, 두 번째는 동적이며 함수의 체인 호출에 의존하기 때문에 동적이라고합니다.

나는 눈에 대한 정적 범위 지정이 더 쉽다는 것을 알았습니다. 대부분의 언어는 결국 이런 식으로 갔다. 심지어 Lisp도 마찬가지이다. 동적 범위 지정은 모든 변수의 참조를 호출 된 함수에 전달하는 것과 같습니다.

컴파일러가 함수의 외부 동적 범위를 추론 할 수없는 이유의 예로 마지막 예제를 고려하십시오. 다음과 같이 작성하면 :

if(/* some condition */)
    dummy1();
else
    dummy2();

호출 체인은 런타임 조건에 따라 다릅니다. 맞다면 콜 체인은 다음과 같습니다.

dummy1 --> fun()

조건이 거짓 인 경우 :

dummy2 --> fun()

fun두 경우 모두 외부 범위 는 발신자 및 발신자의 발신자 등입니다 .

C 언어는 중첩 함수 나 동적 범위 지정을 허용하지 않습니다.


답변

가장 짧은 정의를 시도해 보겠습니다.

어휘 범위 지정 은 중첩 함수에서 변수 이름을 확인하는 방법을 정의합니다. 내부 함수에는 상위 함수가 반환 된 경우에도 상위 함수의 범위가 포함 됩니다.

그것이 전부입니다!


답변

var scope = "I am global";
function whatismyscope(){
   var scope = "I am just a local";
   function func() {return scope;}
   return func;
}

whatismyscope()()

위의 코드는 “나는 단지 로컬입니다”를 반환합니다. “나는 글로벌입니다”를 반환하지 않습니다. func () 함수는 whatismyscope 함수의 범위에 속하는 원래 정의 된 위치를 계산하기 때문입니다.

그것이 호출되는 것이 무엇이든 (글로벌 범위 / 다른 함수 내에서도) 귀찮게하지 않을 것입니다. 그래서 내가 글로벌 인 글로벌 범위 값이 인쇄되지 않습니다.

이를 “어휘 범위 지정”이라고합니다. 여기서 JavaScript 정의 안내서에 따르면 ” 함수를 정의 할 때 적용되었던 스코프 체인을 사용하여 함수가 실행됩니다 “.

어휘 범위는 매우 강력한 개념입니다.

도움이 되었기를 바랍니다..:)


답변

어휘 (AKA 정적) 범위 지정은 텍스트 코드 모음 내 위치 만 기준으로 변수 범위를 결정하는 것을 말합니다. 변수는 항상 최상위 환경을 나타냅니다. 동적 범위관련하여 이해하는 것이 좋습니다 .


답변

범위는 기능, 변수 등을 사용할 수있는 영역을 정의합니다. 예를 들어 변수의 가용성은 컨텍스트 내에서 정의됩니다. 함수, 파일 또는 객체가 정의되어 있다고합시다. 일반적으로 이러한 로컬 변수를 호출합니다.

어휘 부분은 소스 코드를 읽지 않고 범위를 파생시킬 수 있음을 의미합니다.

어휘 범위는 정적 범위라고도합니다.

동적 범위는 정의 후 어디서나 호출하거나 참조 할 수있는 전역 변수를 정의합니다. 대부분의 프로그램 언어의 전역 변수가 어휘 범위에 있더라도 전역 변수라고도합니다. 이는 변수가이 컨텍스트에서 사용 가능하다는 코드를 읽음으로써 파생 될 수 있음을 의미합니다. 아마도 instatiation 또는 정의를 찾기 위해 uses 또는 contains 절을 따라야 할 수도 있지만 코드 / 컴파일러는이 위치의 변수에 대해 알고 있습니다.

반면에 동적 범위 지정에서는 먼저 로컬 함수를 검색 한 다음 로컬 함수를 호출 한 함수를 검색 한 다음 해당 함수를 호출 한 함수 등을 호출 스택에서 검색합니다. “동적”은 주어진 함수가 호출 될 때마다 호출 스택이 다를 수 있으므로 함수가 호출되는 위치에 따라 다른 변수에 부딪 칠 수 있다는 점에서 변경을 나타냅니다. ( 여기 참조 )

동적 범위에 대한 흥미로운 예를 보려면 여기를 참조 하십시오 .

자세한 내용은 여기여기를 참조 하십시오 .

델파이 / 오브젝트 파스칼의 예제

델파이는 어휘 범위를 가지고 있습니다.

unit Main;
uses aUnit;  // makes available all variables in interface section of aUnit

interface

  var aGlobal: string; // global in the scope of all units that use Main;
  type
    TmyClass = class
      strict private aPrivateVar: Integer; // only known by objects of this class type
                                    // lexical: within class definition, 
                                    // reserved word private   
      public aPublicVar: double;    // known to everyboday that has access to a 
                                    // object of this class type
    end;

implementation

  var aLocalGlobal: string; // known to all functions following 
                            // the definition in this unit    

end.

델파이가 동적 범위에 가장 가까운 것은 RegisterClass () / GetClass () 함수 쌍입니다. 사용 방법은 여기를 참조 하십시오 .

RegisterClass ([TmyClass])가 특정 클래스를 등록하기 위해 호출 된 시간은 코드를 읽음으로써 예측할 수 없습니다 (사용자가 호출 한 버튼 클릭 메소드에서 호출 됨). GetClass ( ‘TmyClass’)를 호출하는 코드는 결과 또는 아닙니다. RegisterClass () 호출은 GetClass ()를 사용하여 어휘 범위 내에있을 필요는 없습니다.

동적 범위의 또 다른 가능성 은 델파이 2009의 익명 메소드 (클로저)입니다. 호출 함수의 변수를 알고 있기 때문입니다. 재귀 적으로 호출 경로를 따르지 않으므로 완전히 동적이지 않습니다.


답변

@Arak과 같은 사람들의 모든 기능을 갖춘 언어에 구애받지 않는 답변을 좋아합니다. 이 질문은 JavaScript 로 태그 되었으므로이 언어에 매우 특정한 메모를 작성하고 싶습니다.

JavaScript에서 범위를 지정하기위한 선택은 다음과 같습니다.

  • 있는 그대로 (범위 조정 없음)
  • 어휘 var _this = this; function callback(){ console.log(_this); }
  • 경계 callback.bind(this)

JavaScript 에는 실제로 동적 범위 가 없다는 점은 주목할 가치가 있습니다. .bind조정this키워드를 가깝지만 기술적으로는 다릅니다.

다음은 두 가지 방법을 모두 보여주는 예입니다. 콜백 범위 지정 방법에 대한 결정을 할 때마다 약속, 이벤트 핸들러 등에 적용됩니다.

어휘

다음은 Lexical ScopingJavaScript에서 콜백 이라는 용어 입니다.

var downloadManager = {
  initialize: function() {
    var _this = this; // Set up `_this` for lexical access
    $('.downloadLink').on('click', function () {
      _this.startDownload();
    });
  },
  startDownload: function(){
    this.thinking = true;
    // Request the file from the server and bind more callbacks for when it returns success or failure
  }
  //...
};

경계

범위를 정하는 또 다른 방법은 다음을 사용하는 것입니다 Function.prototype.bind.

var downloadManager = {
  initialize: function() {
    $('.downloadLink').on('click', function () {
      this.startDownload();
    }.bind(this)); // Create a function object bound to `this`
  }
//...

이 방법들은 내가 아는 한 행동 상 동일합니다.


답변

어휘 범위 : 함수 외부에서 선언 된 변수는 전역 변수이며 JavaScript 프로그램의 모든 곳에서 볼 수 있습니다. 함수 안에 선언 된 변수는 함수 범위를 가지며 해당 함수 안에 나타나는 코드에만 표시됩니다.