일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- custom printing
- github pdf
- react-native
- Failed to compiled
- npm package
- nextjs
- html
- camera permission
- Git
- github 100mb
- 이미지 데이터 타입
- Recoil
- electron-packager
- Can't resolve
- adb connect
- react-native-dotenv
- github lfs
- dvh
- animation
- augmentedDevice
- 티스토리 성능
- ELECTRON
- camera access
- Each child in a list should have a unique "key" prop.
- vercel git lfs
- silent printing
- device in use
- ffi-napi
- adb pair
- rolldown
- Today
- Total
Bleeding edge
2022/08/12 - TIL 본문
13장 스코프
13.1 스코프란?
var 키워드로 선언한 변수와 let, const키워드로 선언한 변수의 스코프는 다르게 동작한다. 스코프는 변수 그리고 함수와 깊은 관련이 있다.
스코프는
- 코드의 가장 바깥
- 코드 블록내
- 중첩된 코드 블록 내에서 선언한
- 함수 내에서 선언한 변수
- 중첩된 함수 내에서 선언한 변수
모든 식별자는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효범위가 정해진다. 즉 스코프는 식별자가 유효한 범위를 말한다.
스코프란, 식별자를 검색할 때 사용하는 규칙
주변에 어떤 코드가 있는지를 렉시컬 환경이라고 부르며, 코드의 문맥은 렉시컬 환경으로 이루어지며, 이를 구현한 것이 실행 컨텍스트이며, 모든 코드는 실행 컨텍스트에 의해 평가되고 실행된다.
스코프는 네임 스페이스다(식별자의 이름이 유효한 범위)
네임 스페이스 : 개체를 구분할 수 있는 범위를 나타내는 말로
일반적으로 하나의 이름 공간에서는 하나의 이름이 단 하나의 개체만을 가리키게 된다
13.3 스코프 체인
var x = 0;
function outerFunction{
var x = 1
function innerFunction{
var x =2;
function coreFunction{
var x=3;
}
}
}
위의 코드처럼 계층별로 스코프가 연결된 것을 스코프 체인이라고 한다. 변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색한다.
13.4 함수 레벨 스코프
지역은 함수 몸체 내부를 말하고, 코드 블록이 아닌 함수에 의해서만 지역 스코프가 생성된다.
- 블록 레벨 스코프 : if, for, while, try/catch 등의 스코프로 인정
- 함수 레벨 스코프 : 오직 함수만을 스코프로 인정
13.5 렉시컬 스코프
- 함수를 어디서 호출 했는지 : 동적 스코프
- 함수를 어디에 정의 했는지 : 정적, 렉시컬 스코프(자바스크립트)
함수의 상위 스코프는 언제나 자신이 정의된 스코프이다.
렉시컬 스코프는 클로저와 깊은 관계가 있다.
14장 전역 변수의 문제점
전역 변수를 반드시 사용해야 할 이유를 찾기 못한다면, 지역변수를 사용해야 한다
14.1 변수의 생명 주기
14.1.1 지역 변수의 생명주기
변수는 선언에 의해 생성되고, 할당을 통해 값을 갖는다. 그리고 언젠가 소멸한다.
지역 변수는 함수가 호출되기 전까지 생성되지 않는다. 지역 변수의 생명주기는 함수의 생명주기와 일치한다. 지역 변수의 생명 주기는 함수 생명 주기와 대부분 일치하지만, 지역 변수가 함수보다 오래 생존하는 경우가 존재한다.
변수는 자신이 등록한 스코프가 소멸할 때 까지 유효하다. 누군가 스코프를 참조하고 있으면 스코프는 소멸하지 않고 생존하게 된다.
호이스팅은 스코프를 단위로 동작한다.
14.1.2 전역 변수의 생명 주기
var 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 된다. 이는 전역변수의 생명 주기가 전역 객체의 생명주기와 일치한다는 것을 말한다
14.2 전역 변수의 문제점
변수의 유효범위가 크면 클수록, 코드의 가독성은 나빠지고, 상태가 변경될 수 있는 위험성도 높아진다. 전역 변수는 스코프 체인 상에서 종점이 존재한다. 전역 변수는 가장 마지막에 검색되기 때문에, 전역 변수의 검색 속도가 가장 느리다. 자바스크립트의 가장 큰 문제점은 파일이 분리되어 있다 해도 하나의 전역 스코프를 공유한한다.
14.3 전역 변수의 사용을 억제하는 방법
14.3.1 즉시 실행 함수
모든 코드를 즉시 실행 함수로 감싸면 모든 변수는 즉시 실행 함수의 지역변수가 된다,
14.3.2 네임스페이스 객체
네임스페이스 역활을 담당할 객체를 생성하고, 변수를 프로퍼티로 추가하는 방법이다.
(네임스페이스 자체가 전역변수에 할당되므로, 그다지 유용해 보이지 않는다)
14.3.3 모듈 패턴
자바스크립트의 가장 강력한 기능인 클로저를 기반으로 동작한다. 캡슐화는 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조를 참조하고, 조작할수 있는 동작인 메서드를 하나로 묶는 것을 말한다.
다른 언어와 다르게 자바스크립트는 public, private, protected 등의 접근 제한자를 제공하지 않기에, 모듈 패턴은 전역 네임스페이스의 오염을 막는 기능은 물론 한정적이기는 하지만, 정보 은닉을 구현하기 위해 사용한다
var Counter = ( function() {
//private 변수
var num = 0;
//외부로 공개할 데이터나 메서드를 프로퍼티로 추가한 객체를 반환한다
return{
increase(){
return ++num;
}
decrease(){
return --num;
}
}
}());
//private 변수는 외부로 노출되지 않는다.
console.log(Counter.num)//undefined
console.log(Counter.increase());
console.log(Counter.decrease());
Counter(즉시 실행 함수)는 객체를 반환한다.
14.3.4 ES6 모듈
ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공한다.
<script type="module" src="app.mjs"></script>
15장 let const 키워드와 블록 레벨 스코프
15.1 var 키워드로 선언한 변수의 문제점
15.1.1 변수 중복 선언 허용
의도치 않게, 먼저 선언된 변수 값이 변경되는 부작용이 발생한다
15.1.2 함수 레벨 스코프
외부에서 선언한 변수도 코드 블록 내에서 선언해도 모두 전역변수가 된다.
(for문으로 선언해도 전역 변수가 된다)
15.1.3 변수 호이스팅
var 키워드로 선언하면, 선언과 동시에 초기화(undefined로)가 되고 런타임이 되면, undefined로 반환된다.
15.2 let 키워드
15.2.1 변수 중복 선언 금지
var foo =123;
var foo =456;
let bar =123;
let bar =456; SyntaxError bar has already benn declared;
15.2.2 블록 레벨 스코프
15.2.3 변수 호이스팅
var 키워드 같은 경우 선언한 변수는 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언 단계와 초기화 단계가 한번에 진행된다.
let 키워드로 선언한 변수는 런타임 단계전에서 선언되고, 변수 선언문에 도달했을 때, 초기화된다. 만일 , 이전에 변수에 접근하려고 하면 참조 에러(선언은 됬으나, 아직 초기화가 안된)가 뜬다. 스코프 시작 지점부터 변수를 참조할 수 없는 구간을 일시적 사각지대(TDZ)라고 한다.
let foo= 1;
{
console.log(foo); //ReferenceError : Cannot access 'foo' before initialization
let foo =2;
}
15.2.4 전역 객체와 let
let 키워드로 선언한 전역 변수는 전역 객체 프로퍼티가 아니다. 즉 window.foo와 같이 접근할 수 없다.
let x = 1;
console.log(window.x);//undefined
console.log(x);//1;
15.3 const 키워드
15.3.1 선언과 초기화
const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화해야 한다.
const foo; SyntaxError : Missing initializer in const declaration
const 키워드로 선언한 변수는 let 키워드로 선언한 변수와 마찬가지로 블록 레벨 스코프를 가지며, 변수 호이스팅이 발생하지 않는 것처럼 동작한다.
15.3.2 재할당 금지
var 또는 let 키워드로 선언한 변수는 재할당이 자유로우나 const키워드로 선언한 변수는 재할당이 금지되어 있다.
15.3.3 상수
상수는 재할당이 금지된 변수를 말한다. 상수는 저장하기 위한 메모리 공간이 필요하므로 변수라고 할 수 있다. const 키워드로 선언된 변수에 원시 값을 할당한 경우 원시 값은 변경할 수 없는 값이고 const 키워드에 재할당이 금지되어 잇으므로, 할당된 값을 변경할 수 있는 방법은 없다.
상수 네이밍(스네이크 케이스)
1. 숫자
cosnt TAX_RATE = 0.1;
2. 객체
const tax_list ={
taxRate : 0.1,
unPaidPeople:1000a
}
15.3.4 const 키워드와 객체
객체의 프로퍼티는 바뀔 수 있지만, 참조 값은 변경되지 않는다.(재할당이 금지지, 불변을 의미하지 않는다)
15.4 var vs let vs const
변수 선언에는 기본적으로 const를 사용하고 let은 재할당이 필요한 경우에 한정해 사용하는 것이 좋다
- ES6를 사용한다면 var 키워드를 사용하지 않는다
- 재할당이 필요한 경우에 한정해 let 키워드를 사용한다. 이때 변수의 스코프는 최대한 좁게 만든다
- 읽기 전용으로 사용하는 원시 값과 객체에는 const를 사용한다
일단 const를 사용하고 재할당이 필요할 때 const를 let을 사용하는 것이 좋다.
'ConnecTo' 카테고리의 다른 글
2022/08/17 - TIL (0) | 2022.08.17 |
---|---|
2022/08/16 - TIL (0) | 2022.08.16 |
2022/08/11 - TIL (0) | 2022.08.11 |
2022/08/10 - TIL (0) | 2022.08.10 |
2022/08/09 - TIL (0) | 2022.08.09 |