
원시 자료형은 값(value)을 저장하고 참조 자료형은 주소(reference)를 저장한다.
- 원시 자료형 : number, string, undefined, boolean, bigInt, symbol, (null)
- 참조 자료형 : 배열, 객체
let num1 = 1; let num2 = num1; num1 = 3; console.log(num2); // 1 console.log(num1); // 3원시 자료형에는 값 자체가 할당되기 때문에 num1에 3을 할당해도 num2의 값은 바뀌지 않는다.
let arr1 = [1, 2, 3]; let arr2 = arr1; arr2[2] = 6; console.log(arr1[2]); // 6참조 자료형에는 주소 값이 할당되기 때문에
arr1과arr2는 같은 주소를 공유하게 된다. 따라서 둘 중 하나의 값이 바뀌면 나머지 하나의 값도 바뀐다.
c언어의
malloc과 비슷한 개념이다.
스코프(Scope)는 변수의 접근 규칙에 따른 유효성 범위를 뜻한다.
let username = 'kimbob'; if (username) { let message = `Hello, ${username}!`; console.log(message); // Hello kimbob! } console.log(message); // ReferenceError여기서 중괄호
{ }로 둘러쌓인 부분을 안쪽 스코프, 바깥을 바깥쪽 스코프라고 한다. 바깥쪽 스코프에서 선언된 변수는 안쪽 스코프에서 사용할 수 있지만, 안쪽 스코프에서 선언된 변수는 바깥에서 사용할 수 없다. 이것이 바로 유효성 범위이다. 자세한 내용은 아래를 살펴보자.
스코프는 중첩이 가능하다 !
스코프에는 두 가지 종류가 있다. 블록 스코프(block scope)는 중괄호
{ }로 둘러싼 범위이고, 함수 스코프(function scope)는 함수로 둘러싼 범위이다. (❗ 화살표 함수는 블록 스코프에 포함된다.)
스코프 중 가장 바깥쪽의 스코프를 우리는 특별히 전역 스코프(global scope)라고 부른다. 그 외의 스코프는 지역 스코프(local scope)라고 부른다.
지역 변수는 전역 변수보다 더 높은 순위를 갖고있다.
let greeting = 'Hello'; let greets = () => { let greeting = 'Bonjour!'; console.log(greeting); // Bonjour! }여기서 function 속의 greeting은 지역 변수이다. 따라서
console.log(greeting)에 출력되는 내용은 지역 변수 greeting의 값인'Bonjour!'가 된다.
변수를 선언할 수 있는 키워드에는 세 가지가 있다.
var: 블록 스코프를 무시하고 함수 스코프만 따른다.(화살표 함수 포함)let: 블록 스코프, 함수 스코프 모두 따른다. 재선언을 방지하기 때문에 블록 단위 예측이 가능하다.const: 상수(constant) 역할을 한다. 값의 변경이 불가능하다. 값을 재할당 할 경우 TypeError 가 발생한다. 안전한 프로그램을 만들기 위해서는, 변수에 값을 재할당할 핗요가 없다면const키워드를 사용하여 선언 해주는 것이 좋다.
브라우저에만 존재하는, 브라우저 창을 의미한다. 하지만 전역 영역을 담고 있기도 하다.
var로 선언한 변수나 함수가 포함된다.var vegetable = 'carrot'; console.log(window.vetgetable); // carrot때문에 전역 변수를
var로 선언할 경우 window가 망가질 수도 있다 !
클로저(closure)란, 함수와 함수가 선언된 어휘적 환경(변수 및 함수 선언의 형태)의 조합이다. 클로저 함수는 외부 함수의 변수에 접근이 가능한 내부 함수를 일컫는다.
const adder = function(x) { return function(y) { return x + y; } }여기서 외부 함수는 리턴 값이 함수 형태이며, 내부 함수는 외부 함수의
x값에 접근할 수 있다.
리턴하는 함수(내부 함수)의 스코프는 외부 함수에 접근할 수 없다. 이를 '스코프를 이용하여 변수의 접근 범위를 닫는다' 고 이야기한다.
1) 데이터를 보존하는 함수
위에서 이야기 했듯이, 내부 함수는 외부 함수의 변수에 접근이 불가능하다. 때문에 이를 이요하면, 외부 함수의 변수 값을 보존하며 함수를 사용할 수 있다. 위에서 쓴 adder 함수를 예로 들어보자.const add5 = adder(5); add5(7); // 12 add5(18); // 23외부 함수
adder의 실행이 끝나더라도, 변수x의 값은 변하지 않았기 때문에 계속 사용이 가능하다 ! 이는 태그를 만들 때 유용하게 쓰인다.2) 정보의 접근 제한
function makeCounter() { let privCounter = 0; return { increment: function(){ privCounter++; }, decrement: function(){ privCounter--; }, getValue: function(){ return privCounter; } } }위 함수는 은 클로저의 모듈 패턴이다. 외부 함수는 함수 여러 개를 포함한 '객체'를 반환한다. 이 경우
makeCounter함수를 바꾸지 않고는 value 값을 조정할 수 없다. 이를 정보의 접근 제한(캡슐화)이라고 이야기한다.3) 모듈화
함수의 재사용을 극대화하여 함수 자체를 독립적인 부품 형태로 분리한다. 데이터와 메소드를 같이 묶어서 다룰 수 있다.
배열을 풀어서 인자로 전달하거나, 배열을 풀어 각각의 요소로 넣을 때 사용한다.
function sum(x, y, z) { return x + y + z; } const numbers = [1, 3, 5]; sum(...numbers); // 9
파라미터를 배열의 형태로 받아서 사용한다. 파라미터 개수가 가변적일 때 유용하다.
function sum(...theArgs) { return theArgs.reduce((previous, current) => { return previous + current; }); } sum(1, 2, 3) // 6 sum(1, 5, 6, 8) // 20이를 활용하여 배열과 객체를 합치고 복사하는 것이 가능하다. 함수에서 나머지 파라미터를 받아올 때도 유용하게 사용된다.
구조 분해 (Destructing) : Spread 문법으로 값을 해체할 후 개별 값을 변수에 새로 할당 해주는 것을 이야기한다. (분해 후 새 변수에 할당)
const [a, b, ...rest] = [1, 2, 3, 4, 5, 6, 7]; a; // 1 b; // 2 rest; // [3, 4, 5, 6, 7]
얕은 복사: 참조(주소)값의 복사 ➡ 한 데이터를 공유하는 것
깊은 복사: 값 자체의 복사 ➡ 독립적인 메모리에 값 자체를 할당하여 생성하는 것ex)
- 원시 자료형 : 깊은 복사
- 참조 자료형 : 얕은 복사
- Object.assign : 깊은 복사(객체 제외)
const obj = { john: 'apple'; charlie: 'banana'; else : {jane: 'peach', tom: 'kiwi', sarah: 'pineapple'} } const copiedObj = Object.assign({}, obj);위 함수에서
john과charlie는 깊은 복사가 되지만,else는 얕은 복사가 되어obj와copiedObj는 같은 주소를 공유하게 된다.
- 구조 분해 병합으로 생선된 객체 : 깊은 복사(객체 제외)
오늘 너무 많은 정보를 한 번에 머리에 쑤셔 넣어서 뇌가 아주 꾸깃 꾸깃 해졌다. 그래도 TIL 작성하면서 다시 좀 예쁘게 펴진 것 같다. 내일 일어나서 한번 더 보면 더 예쁘게 펴지겠지 ! 오늘도 고생했다 나 자신 🧚♀️