티스토리 뷰
반응형
- 해당 문서는 JS 공부 중 정리하게된 내용이기에 JS 기준으로 작성되었습니다.
- 해당 문서는 아래의 블로그 글들을 나름대로 정리한 것이므로, 아래의 링크를 통해 훨씬 상세한 내용을 확인하실 수 있습니다.
참고 :
- https://hyunseob.github.io/2016/09/17/lambda-anonymous-function-closure/
- https://medium.com/@khwsc1/%EB%B2%88%EC%97%AD-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%8A%A4%EC%BD%94%ED%94%84%EC%99%80-%ED%81%B4%EB%A1%9C%EC%A0%80-javascript-scope-and-closures-8d402c976d19
- https://hyunseob.github.io/2016/08/30/javascript-closure/
0. JS Scope
- 어떤 변수들에 접근할 수 있는지, 범위를 정의하는 개념
i). Global Scope(전역 스코프)
- 변수가 밖에 선언된 경우, 전역 스코프에 선언된 전역 변수가 된다.
- 전역 변수는 코드의 모든 곳으로부터 접근이 가능하다.
const ingnoh = "Hello ingnoh";
function whoami() {
console.log(ingnoh);
// Hello ingnoh
}
console.log(ingnoh);
// Hello ingnoh
- 다음 예시와 같은 충돌 문제로 인해, 전역 스코프에는 되도록 변수를 선언하지 않는 것이 좋다.
- var로 선언된 변수 : 해당 변수 내용이 덮어 씌워짐.
- let으로 선언된 변수 : 해당 변수가 충돌되므로 에러가 발생
- 두 경우 모두 에러 또는 디버깅이 어려워지는 원인이 되므로 지양하는 것이 좋음.
var varIngnoh = "Hello"; // Hello
var varIngnoh = "World"; // World(덮어씌움)
let letIngnoh = "Hello"; // Hello
let letIngnoh = "World"; // Error occurred! letIngnoh has already been declared...
ii). Local Scope(지역 스코프)
- 지역 스코프에 정의된 변수는 지역 변수로서, 특정 부분(블록, {})에서만 사용이 가능하다.
- JS에서는 두 가지 지역 변수 형식이 존재한다.
- Function scope : 함수 내부에서 선언된 변수는 함수 내에서만 접근이 가능하다.
- Block scope : 특정한 중괄호 내부에서 let 또는 const로 선언된 변수는 블록 내부에서만 접근이 가능하다.
- 함수 선언시 중괄호를 사용하게 되므로, Block scope는 Function scope의 서브셋이다.
iii). Function Hoisting(함수 호이스팅)
- JS에서 함수를 선언하는 방법은 두 가지 방식이 있다 :
- 함수 선언식(Function declaration) : function ingnoh() {}
- 함수 선언식으로 선언된 함수는, 현재 스코프의 최상단으로 호이스팅된다.
- 함수 표현식(Function expression) : function ingnoh = function() {}
- 함수 표현식으로 선언된 함수는, 현재 스코프의 최상단으로 호이스팅되지 않는다.
- 함수 선언식(Function declaration) : function ingnoh() {}
- 함수 호이스팅은 혼란을 줄 수 있으므로 되도록 지양해야하며, 함수를 호출하기 전에 선언해두는 방식이 권장된다.
ingnoh();
function ingnoh() {
console.log("Hello ingnoh");
}
// 위, 아래 모두 결과는 같다.
/*
function ingnoh() {
console.log("Hello ingnoh");
}
ingnoh();
*/
ingnoh(); // Error occurred! ingnoh is not defined
let ingnoh = function() {
console.log("Hello ingnoh");
}
iv). Nested Scopes
- 함수가 다른 함수 내부에 정의된다면, 내부 함수는 외부 함수의 변수에 접근할 수 있다.( = lexical scoping)
- 반면 외부 함수는 내부 함수의 변수에 접근할 수 없다.
1. Closure
- 함수 내부에 또 다른 함수를 작성했다면, 내부의 함수는 클로저가 된다.
- 클로저는 외부 함수의 변수에 접근할 수 있으므로, 대부분 return을 위해 사용한다.
function outsideIngnoh(hello) {
return function insideIngnoh(world) {
console.log(hello + world);
}
}
let ingnoh = outsideIngnoh("hello ");
ingnoh("world"); // console.log("hello world");
- 위 예시로부터, ingnoh의 입장에서 변수 hello는 그 출처를 알 수 없는 변수인 자유 변수가 된다.
- 반면 변수 world는 자신의 매개 변수로 받아 처리하므로 출처를 알 수 있는 변수인 묶인 변수로 취급한다.
- 클로저는 이와 같은 자유 변수를 자신의 스코프 내로 가져와 묶인 변수로 만든다. 때문에 마치 실행 환경을 기억하는 것처럼 동작한다.
- 클로저는 주로 ajax 비동기 처리 또는 timeout과 같이 코드 흐름을 방해하는 상황에서 사용된다.
- timeout을 사용한 closure 예제는 다음과 같다.
// ingnoh 는 name과 함께 호출된 1초 이후에 반드시 console.log를 실행
function ingnoh(name) {
setTimeout(function() {
console.log(name);
}, 1000);
}
// Closure 사용시 매개 변수(name) 입력과 함수 호출 시점을 달리할 수 있음
function closureIngnoh(name) {
return function() {
setTimeout(function() {
console.log(name);
}, 1000);
}
let ingnoh = closureIngnoh("ingnoh");
ingnoh();
- Closure는 함수 실행이 끝난 후에도, 함수 호출 시의 환경을 기억하는 듯 보이는 데에 의의가 있다.
- 아래의 예시는 ingnoh를 호출할 때 ingnoh 내부 변수인 hello의 값을 클로저가 참조한다.
- 그러나 호출이 끝난 후 ingnoh 함수가 종료되더라도, 마치 hello 변수의 값이 유지되는 것처럼 동작한다. 즉, 클로저는 환경을 기억하는 것처럼 보인다.
- 또한, 각각의 클로저는 서로 다른 환경을 가지며 기억한다. (= ingnoh1, ingnoh2, ingnoh3의 호출 결과가 다르다.)
function ingnoh(name) {
let hello = "hello " + name;
return function() {
console.log(hello);
}
}
let ingnoh1 = ingnoh("ingnoh1");
ingnoh1(); // hello ingnoh1
let ingnoh2 = ingnoh("ingnoh2");
ingnoh2(); // hello ingnoh2
let ingnoh3 = ingnoh("ingnoh3");
ingnoh3(); // hello ingnoh3
2. Anonymous Function(익명 함수)
- 익명 함수는 이름을 정의하지 않고 사용하는 함수로, 대표적으로 콜백이 있다.
- 콜백은 명명된 함수를 사용해도 좋지만, 일반적으로는 익명 함수를 사용한다고 함.
- 이름을 정의하지 않으므로 다시 호출하는데에 어려움이 있고, 때문에 일회용으로 사용하는 함수에 적절하다.
- 클로저 역시 익명 함수를 사용하므로 두 용어가 혼용되곤 한다고 함.
- 클로저 : 함수 내부에 정의되어 사용되는 함수가 있는 경우이며, 대개는 정의된 함수를 익명 함수의 형식으로 리턴한다.
- 익명 함수 : 함수에 이름을 정의하지 않고 사용하는 경우를 말하며, 대표적으로는 콜백 함수가 있다.
3. Furthermore - Arrow Function(화살표 함수)
- JS에서의 람다식으로 이해할 수 있다.
- (매개변수) => { 함수내용 } 과 같은 형식으로 정의한다.
let ingnoh1 = function(name) {
console.log(name);
}
let ingnoh2 = (name) => { console.log(name); }
'Dev. > javascript' 카테고리의 다른 글
[jQuery] best practice - DOM manipulation (0) | 2021.02.17 |
---|---|
[jQuery] best practice - jQuery Ready Event (0) | 2021.02.16 |
[jQuery] substr, substring (0) | 2020.11.19 |
[jQuery] ace editor 간단 설정 (1) | 2020.09.21 |
[jQuery] checkbox 개수 및 전체 선택 (0) | 2020.09.04 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Docker
- etc
- 코딩테스트
- Gradle
- react
- Vault
- javascript
- kotlin
- IntelliJ
- mysql
- shell
- jQuery
- RancherDesktop
- Git
- hashicorp
- Node.js
- spring boot
- JEST
- Linux
- pgloader
- Java
- Puppeteer
- AWS
- eureka
- Spring Cloud Config
- JPA
- AWS IoT
- postgresql
- terraform
- Database
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함