예제
func1()의 값이 왜 3일까?
전역에 a = 20을 해주었는데?
함수 안에 있는 a는 함수 안에서만 존재하고, 전역에 있는 a는 영향을 미치지 못한다.
=> 함수 선언 다음에 있어서 , 값을 할당했지만 함수 스코프안에 있는 a가 반영된다.
함수 밖에서 b의 값을 알아보고 싶어도? 알아볼 수 없다.
=> 함수 스코프 공간 안에 있기 때문에, 전역에서는 함수 스코프 안으로 접근 할 수 없다.
즉, 스코프는 이름 충돌 문제를 덜어주고, 자동으로 메모리를 관리한다
다른 공간에 있기 때문에, 변수의 이름이 같아도 원하는 결과를 얻을 수 있다.
함수 스코프 안에 있는 변수는 함수가 리턴되면 모두 해제됨
: 스크립트의 어디서든 접근이 가능하기 때문에 사용이 쉽다. 하지만 타인과의 협업, 라이브러리 사용시 충돌의 가능성이 있다.
: 함수 내부에서 정의된 변수와 매개변수는 함수 외부에서 접근할 수 없다.
함수 내부에서 정의된 변수라면 함수의 어느 부분에서도 접근할 수 있다.
func1()가 실행되면서 12가 출력되었다.
func2()안에서는 a라는 변수를 선언한 적이 없다.
하지만 func2는 부모함수 안에서 선언된 함수이기 때문에 부모 함수 안을 탐색할 수가 있게 된다.
그렇게 변수 a를 사용할 수 있게 되었다.
전역 공간에서 어떻게 val을 읽어올 수 있었을까?
이는 var을 사용해서 선언한 것이 아니기 때문이다. (선언된 변수가 아니고 전역변수로 인식)
: 중괄호 안에서만 접근이 가능하다.
블록 내부에 정의된 변수는 블록의 실행이 끝나면 해제된다.
let을 사용하게 되면 { } 블록 스코프 안에서만 존재하는 변수가 된다
전역공간에서 value를 접근한다면, var로 선언한 value가 읽힌다.
스코프란 자바스크립트 엔진이 참조의 대상이 되는 식별자(Identifier)를 검색할 때 사용하는 규칙의 집합
즉, 어떤 변수를 사용하거나 함수를 호출하려고 할 때 해당하는 식별자로 사용하는데, 그 식별자를 검색하는 메커니즘이라고 이해하면 된다.
현재 실행되는 컨텍스트
변수가 참조 될 수 있는 접근 가능한 유효 범위
식별자 (변수, 함수, 클래스 이름 등) 가 유효한 범위
만약 변수 또는 다른 표현식이 "해당 스코프"내에 있지 않다면 사용할 수 없음.
선언된 위치에 따라 유효 범위가 결정 된다
스코프는 계층적인 구조를 가지기 때문에 하위 스코프는 상위 스코프에 접근할 수 있지만 반대는 불가하다.
블럭 안의 변수는 블럭 안에서만 유효 - 이름 충돌 방지, 블럭이 끝나면 자동으로 메모리에서 삭제 (절약)
블럭 외부에서는 블럭 내부의 변수를 참조할 수 없다
블럭 : {} , if(){}, for(){}, function(){}
따라서 변수는 최대한 필요한 곳에서 지정해야 함!
변수 및 함수/블록 스코프를 어디에 작성하였는가에 따라 정해지는 스코프 를 렉시컬 스코프라고 한다. "렉시컬(Lexical)" 이라는 명칭이 붙은 이유는 자바스크립트 컴파일러가 소스코드를 토큰(Token)으로 쪼개서 의미를 부여하는 렉싱(Lexing) 단계에 해당 스코프가 확정되기 때문이다. 다시 쉽게 말하면, 변수 혹은 함수/블록이 어디에 써있는가를 보고 그 스코프를 판단하면 된다.
현재 스코프에서 식별자를 검색할 때 상위 스코프를 연쇄적으로 찾아나가는 방식 을 말한다. 실행 컨텍스트를 배웠다면 생성될 때마다 LexicalEnvironment가 만들어지고 그 안에 outer 참조 값이 있다는 것을 알 것이다. 바로 이 outer 참조 값이 상위 스코프의 LexicalEnvironment를 가리키기 때문에 이를 통해 체인처럼 연결되는 것이다.
즉, 다음과 같은 과정으로 스코프 체인을 검색한다.
null
일 때까지 계속하고 찾지 못한다면 에러를 발생시킨다.