string
, number
, bigint
, boolean
, undefined
, symbol
, null
array
, object
, function
(원시 자료형이 아닌 모든 자료형)
{
{
{}
}
}
// 제일 바깥쪽 scope : global scope (전역 스코프)
// 안쪽 scope: local scope (지역 스코프)
// 전역변수(전역 스코프의 변수), 지역변수(지역 스코프의 변수)
// 안쪽 스코프에서는 바깥쪽 스코프 변수에 접근 가능하지만, 밖에서는 안에 접근하지 못한다.
// block scope : {}, if {}, for {}, 화살표 함수 {}
// function scope : function {}
// var 키워드는 는 블록 스코프를 무시하고 함수 스코프만 적용되므로 사용이 권장되지 않음.
// 예) for 문에서 var = i 한다면 i 값을 스코프 밖에서도 접근할 수 있음.
// 또한 재선언을 해도 오류를 내지 않음.
var a = 1; var a = 2;
// 선언 없이 값을 할당하면 var 로 처리됨.
c = 1; // var c = 1;
// const 는 재선언, 재할당 모두 불가.
window
객체는 브라우저에 존재하는 객체이다. 브라우저 창 (window)을 의미하여, 전역 영역을 담고 있다.
//var 로 선언된 전역변수 및 전역함수는 window 객체에 속하게 된다. (다른 키워드는 안됨)
var a = 1;
window.a // 1
// var 로 선언한 변수가 window 객체의 기능을 덮어씌워서 문제가 발생할 수도 있음.
var console = 1;
console.log('abac') // Error: console.log is not a function
'strict mode'
를 쓰면 값의 재선언, 키워드 없는 선언 등의 오류를 잡아준다.[Stack Overflow] How do JavaScript closures work?
클로져는 다음 두 개의 조합이다:
클로져는 함수가 호출됨과 동시에 생성된다.
// 클로저 함수의 기본 형태
const adder = function(first) {// 외부함수
let a = 'hello';
return function(second) {// 내부 함수를 return
console.log(a); // 외부 스코프의 변수에 접근
return first + second; // 외부 함수의 parameter 에 접근
}
}
// 화살표 함수로 만들 때
const adder = first => second => first + second;
const add5 = adder(5);
add5(3); // hello 출력, return 값은 8.
// adder(5)(3) 과 같다. 첫번째 값이 5로 고정된 새로운 함수를 만듦.
const tagMaker = function(tag) {
return function(content) {
return `<${tag}>${content}</${tag}>`
}
}
const divMaker = tagMaker('div'); // div 를 만들기 위한 함수로 만든다.
divMaker('나는 천재야'); // <div>나는 천재야</div>
클로저를 이용해 내부 함수 단 하나만 리턴하는 것에 그치지 않고, 여러개의 내부 함수를 객체에 담아 리턴한다. 또한 내부에 변수를 만들어 외부에서 접근하지 못하게 할 수 있다. (c++의 private 멤버변수처럼 사용)
const makeCounter = function(){
let count = 0; // 이 변수는 내부 환경으로써 저장된다.
return { // 객체에 여러개의 내부함수를 담는다.
// 객체의 key 는 함수를 value 로 가질 수 있다. (함수주소)
increase: function() { count++; },
decrease: function() { count--; },
getCount: function() { return count; }
};
}
const counter1 = makeCounter(); // 객체를 return 하기때문에 counter1 은 객체가 된다.
counter1.increase; // 실행 X
counter1.increase(); // 실행.
counter1.getCount(); // 1, count에 접근이 가능.