스코프?
1. 전역 스코프 (Global Scope)
- 정의 : 전역 스코프에 선언된 변수는 프로그램의 모든 영역에서 접근할 수 있습니다.
- 특징 : 전역 객체 `window`의 속성으로 저장되며, 전역 변수는 다른 스크립트나 함수에서도 접근할 수 있기 때문에 남용할 경우 예측하기 어려운 결과를 초래할 수 있습니다.
2. 지역 스코프 (Local Scope)
- 정의 : 함수 내부에서 선언된 변수는 해당 함수 내에서만 유효하며, 함수가 호출될 때마다 새로운 스코프가 생성됩니다.
- 특징 : 함수 스코프라고도 하며, 함수가 종료되면 해당 스코프 내의 변수들은 메모리에서 해제됩니다.
3. 블록 스코프 (Block Scope)
- 정의 : 중괄호 `{}`로 감싸진 블록 내에서만 유효한 스코프를 말합니다.
- 사용 : `let`과 `const`로 선언된 변수는 블록 스코프를 가지며, 반복문이나 조건문과 같이 코드 블록이 있는 곳에서 주로 활용됩니다.
- 예외 : `var`로 선언된 변수는 블록 스코프를 가지지 않고 함수 스코프를 가집니다.
4. 스코프 체인 (Scope Chain)
- 정의 : 자바스크립트는 변수를 참조할 때 현재 스코프에서 변수를 찾고, 없으면 외부 스코프로 범위를 확장해가며 찾는 방식입니다.
- 동작 방식 : 함수 내부에서 외부 함수나 전역 변수에 접근이 필요한 경우, 상위 스코프에서 해당 변수를 찾는 방식으로 동작합니다.
5. 렉시컬 스코프 (Lexical Scope)
- 정의 : 코드가 작성된 위치에 따라 스코프가 결정되며, 함수가 선언된 위치에 따라 상위 스코프가 고정됩니다.
- 특징 : 실행할 때가 아닌 함수를 정의할 때 스코프가 고정됩니다. 자바스크립트는 렉시컬 스코프를 따르기 때문에, 함수가 실행될 때 상위 스코프를 찾지 않고 이미 결정된 스코프를 참조합니다.
6. 클로저 (Closure)
- 정의: 외부 함수의 변수에 접근할 수 있는 내부 함수로, 함수가 생성될 당시의 외부 변수 상태를 유지하는 역할을 합니다.
- 사용예시: 주로 함수가 종료된 이후에도 특정 데이터에 접근하고자 할 때 사용됩니다. 클로저는 주로 함수 내에 또 다른 함수를 반환하거나 콜백 형태로 많이 사용됩니다.
"요약"
- 스코프 유형 : 전역, 지역, 블록 스코프
- 스코프 체인 : 변수를 상위 스코프에서 찾는 체계
- 렉시컬 스코프 : 함수가 정의된 위치에 따라 스코프가 결정
- 클로저 : 외부 변수에 접근 가능한 내부 함수
이와 같은 스코프 체계는 자바스크립트의 실행 컨텍스트와 함께 동작하여 변수 접근 규칙을 정의하고, 코드의 가독성과 메모리 효율성을 높이는 데 중요한 역할을 합니다.
전역변수의 문제점?
1. 네임스페이스 오염 (Namespace Pollution)
- 정의 : 전역 변수는 모든 스크립트와 함수에서 접근할 수 있기 때문에, 여러 개의 스크립트나 코드 파일이 하나의 전역 네임스페이스를 공유하게 됩니다. 이로 인해 다른 코드에서 동일한 이름의 변수를 사용할 경우, 서로 덮어쓰거나 의도하지 않은 오류가 발생할 수 있습니다.
- 예시 : 여러 스크립트에서 동일한 전역 변수 이름을 사용할 경우 값이 덮어써지며 예기치 않은 결과를 초래할 수 있습니다.
2. 가비지 컬렉션 문제 (Garbage Collection Issue)
- 설명 : 전역 변수는 애플리케이션이 종료될 때까지 메모리에 상주하므로 메모리 누수가 발생할 수 있습니다. 특히 자바스크립트가 클라이언트 측 언어로서 브라우저 내에서 동작하는 경우, 불필요하게 사용되는 전역 변수는 메모리 사용량을 증가시킵니다.
- 결과 : 불필요한 전역 변수를 남발하면 브라우저의 성능 저하나 메모리 문제를 일으킬 가능성이 있습니다.
3. 테스트 및 디버깅의 어려움
- 설명 : 전역 변수는 코드의 다양한 부분에서 접근하고 수정할 수 있기 때문에, 특정 오류가 발생했을 때 그 원인을 추적하기가 어렵습니다.
- 디버깅 복잡성 : 디버깅 시 예상치 못한 전역 변수의 상태 변화로 인해 버그를 찾기 어렵고, 코드의 상태를 예측하기가 어려워집니다.
4. 코드 모듈화 방해
- 정의 : 전역 변수를 사용하면 코드의 독립적인 모듈화가 어렵습니다. 다른 코드나 모듈과의 상호작용을 최소화하며 모듈화하려면 지역 변수와 클로저를 사용하는 것이 좋습니다.
- 문제점 : 전역 변수는 함수와 클래스가 독립적으로 동작하는 것을 방해하고, 의존성 없는 모듈화된 코드 작성에 부정적 영향을 미칩니다.
5. 클로저 사용의 제약
- 설명 : 전역 변수는 자바스크립트의 클로저 기능을 활용하는 데 제약을 줍니다. 클로저는 특정 상태를 유지할 수 있는 유용한 메커니즘이지만, 전역 변수가 이를 무분별하게 수정할 경우 원래 클로저의 의도를 유지하기 어렵습니다.
요약
전역 변수는 네임스페이스 오염 , 메모리 관리 문제, 디버깅의 복잡성 증가, 코드 모듈화 방해등의 문제를 일으키므로, 가급적 전역 변수를 줄이고 필요한 경우 즉시 실행 함수나 모듈 패턴, `const`, `let` 등의 블록 스코프 변수를 사용하는 것이 좋은 대안으로 제시됩니다.
let,const 키워드와 블록 레벨 스코프?
1. `let` 키워드
- 정의 : `let`은 변수 선언 키워드로, 변수 값을 업데이트할 수 있으며 블록 레벨 스코프를 따릅니다.
- 특징 :
- 블록(`{}`) 안에서 선언되면 해당 블록 내부에서만 유효하며, 블록이 끝나면 자동으로 사라집니다.
- 동일한 스코프 내에서 같은 이름으로 다시 선언할 수 없습니다. 이는 코드 오류를 줄이고 명확한 변수 관리에 유용합니다.
if (true) {
let x = 10;
console.log(x); // 10
}
console.log(x); // ReferenceError: x is not defined
2. `const` 키워드
- 정의 : `const`는 상수(변경할 수 없는 값)를 선언하는 키워드로, 선언과 동시에 초기화가 필요하며 블록 레벨 스코프를 따릅니다.
- 특징 :
- 선언된 후 값을 변경할 수 없으므로, 상수 값을 지정하거나 변경되지 않아야 하는 변수를 선언할 때 사용됩니다.
- 객체와 배열도 `const`로 선언할 수 있으며, 객체의 속성 값은 변경할 수 있지만, 객체 자체를 다른 값으로 재할당할 수는 없습니다.
const y = 20;
y = 30; // TypeError: Assignment to constant variable.
3. 블록 레벨 스코프 (Block-Level Scope)
- 정의 : 블록 레벨 스코프는 `{}`로 둘러싸인 코드 블록 내에서 변수가 유효한 범위를 의미하며, `let`과 `const`로 선언된 변수는 이 블록 레벨 스코프를 따릅니다.
- 차이점 : 기존의 `var` 키워드는 함수 스코프만을 지원하여 블록 내부에서 선언해도 함수 전체에서 접근할 수 있었습니다. 반면, `let`과 `const`는 블록 레벨에서만 접근 가능하므로 코드의 예측 가능성을 높입니다.
{
let a = 5;
const b = 10;
console.log(a, b); // 5, 10
}
console.log(a, b); // ReferenceError: a is not defined
4. `let`, `const`와 `var`의 비교
- 스코프 :
- `var`: 함수 스코프를 따르며, 함수 외부에서 선언된 `var` 변수는 전역 스코프에 위치하게 됩니다.
- `let`과 `const`: 블록 레벨 스코프를 따르며, 블록 외부에서 접근할 수 없습니다.
- 호이스팅 :
- `var`: 변수 선언이 코드 상단으로 끌어올려지는 호이스팅이 발생합니다.
- `let`과 `const`: 호이스팅은 발생하지만 "일시적 사각지대(TDZ)"에 놓여 초기화 이전에 접근 시 오류가 발생합니다.
요약
`let`과 `const`는 블록 레벨 스코프를 지원하여 변수 범위 관리와 예측 가능성을 높이며, 전역 변수나 함수 레벨 스코프 변수로 인한 오류를 줄이는 데 유용합니다. `const`는 변경 불가능한 상수 값을, `let`은 변경 가능한 변수 값을 선언할 때 적합하여 각각의 특성에 맞게 사용하는 것이 바람직합니다.
프로퍼티 어트리뷰트?
프로퍼티 어트리뷰트의 종류
자바스크립트에서는 프로퍼티 어트리뷰트를 크게 **데이터 프로퍼티 어트리뷰트와 접근자 프로퍼티 어트리뷰트로 나눌 수 있습니다.
1. 데이터 프로퍼티 어트리뷰트
데이터 프로퍼티는 기본적인 값(데이터)을 담는 프로퍼티로, 다음과 같은 4가지 어트리뷰트를 가집니다.
- value :
- 프로퍼티에 저장된 실제 값입니다.
- 기본적으로 모든 데이터 프로퍼티는 이 `value` 어트리뷰트를 통해 값을 가지며, 읽기와 쓰기가 가능합니다.
- writable :
- 프로퍼티의 값을 변경할 수 있는지를 나타냅니다.
- `true`일 경우 프로퍼티 값 변경이 가능하며, `false`일 경우 값이 수정되지 않습니다.
- enumerable :
- 프로퍼티가 열거 가능한지를 나타내며, `for...in` 루프나 `Object.keys` 메서드에 포함될지를 결정합니다.
- `true`면 열거 가능하고, `false`면 열거되지 않습니다.
- configurable :
- 프로퍼티의 삭제 및 어트리뷰트 변경 가능 여부를 결정합니다.
- `true`일 경우 `delete`로 프로퍼티 삭제가 가능하고, 다른 어트리뷰트 수정도 가능합니다.
- `false`일 경우 삭제 및 어트리뷰트 수정이 불가합니다.
let obj = {};
Object.defineProperty(obj, 'name', {
value: 'John',
writable: false,
enumerable: true,
configurable: true
});
console.log(obj.name); // "John"
obj.name = 'Doe'; // writable이 false이므로 변경되지 않음
console.log(obj.name); // "John"
2. 접근자 프로퍼티 어트리뷰트
접근자 프로퍼티는 getter 와 setter 함수를 통해 프로퍼티를 설정하거나 가져올 수 있는 특수한 프로퍼티입니다. 값 자체를 저장하지 않고, 함수를 통해 값을 가져오거나 설정하는 방식으로 동작합니다.
- get :
- 프로퍼티의 값을 가져오는 함수로, 프로퍼티에 접근할 때 호출됩니다.
- 프로퍼티에 접근하면 이 함수가 실행되고 그 결과가 반환됩니다.
- set :
- 프로퍼티에 값을 설정하는 함수로, 프로퍼티에 값을 할당할 때 호출됩니다.
- 프로퍼티에 값을 할당하면 이 함수가 실행되며, 전달된 값은 매개변수로 받습니다.
let user = {
firstName: "John",
lastName: "Doe",
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(name) {
[this.firstName, this.lastName] = name.split(" ");
}
};
console.log(user.fullName); // "John Doe"
user.fullName = "Jane Smith";
console.log(user.firstName); // "Jane"
console.log(user.lastName); // "Smith"
프로퍼티 어트리뷰트 확인 및 수정
- 확인 : `Object.getOwnPropertyDescriptor(obj, prop)` 메서드를 통해 프로퍼티 어트리뷰트를 확인할 수 있습니다.
- 수정 : `Object.defineProperty(obj, prop, descriptor)` 메서드를 사용하여 기존 프로퍼티의 어트리뷰트를 설정하거나 수정할 수 있습니다.
let person = { name: "Alice" };
let descriptor = Object.getOwnPropertyDescriptor(person, 'name');
console.log(descriptor);
// { value: "Alice", writable: true, enumerable: true, configurable: true }
요약
- 데이터 프로퍼티 : `value`, `writable`, `enumerable`, `configurable`
- 접근자 프로퍼티 : `get`, `set`
- 제어 메서드 : `Object.getOwnPropertyDescriptor`, `Object.defineProperty`
프로퍼티 어트리뷰트를 잘 활용하면 객체의 프로퍼티를 보다 정밀하게 제어할 수 있어, 안전하고 예측 가능한 코드를 작성하는 데 도움이 됩니다.
'STUDY_JAVASCRIPT' 카테고리의 다른 글
함수 (0) | 2024.10.29 |
---|---|
객체 리터럴, 원시값과 객체의 비교, 함수 (1) | 2024.10.21 |
모던스크립트 [연산자, 제어문,타입변환과 단축평가] (0) | 2024.10.17 |