1. 변수와 상수
👉 [변수 생성의 3단계] 선언 → 초기화 → 할당
- 선언: 실행 컨텍스트에 변수 객체를 등록 (스코프가 참조하는 대상이 되도록요!)
- 초기화: 변수 객체에 등록된 변수를 위해 메모리에 공간을 확보 (여기서 변수는 보통 undefined로 초기화됩니다!)
- 할당: undefined로 초기화된 변수에 실제 값을 할당
1) var
: var는 가급적 사용하지 않는 게 좋습니다.
- var로 선언한 변수는 블록 스코프가 아닌 함수 수준 스코프를 가집니다.
- var는 선언과 초기화를 한번에 합니다.
- 재선언이 가능합니다.
- 선언하기 전에도 사용 할 수 있습니다.
// var는 이런 식의 사용도 가능합니다. 괴상하죠!
// var name은 선언! name = "perl"은 할당!
function cat(){
name = "perl";
alert(name);
var name;
}
cat();
- 코드 블럭을 무시합니다.
(var는 함수 최상위로 호이스팅을 합니다. 선언은 호이스팅 되고 할당은 호이스팅 되지 않습니다.)
// var name은 함수의 최상위로 호이스팅되기 때문에,
// 실행될 일 없는 구문 속에 있어도 선언이 됩니다.
// (자바스크립트가 동작하기 전에 코드를 한 번 훑는데
// 그 때, var로 선언된 코드를 전부 최상위로 끌어올려버립니다. 동작해선 안되는 구문이라도... 몽땅..!)
function cat(){
name = "perl";
// 이 if문 내로는 절대 들어올 일이 없죠!
if(false) {
var name;
}
alert(name);
}
cat();
2) let
- 자바스크립트에서 변수를 생성 할 때 쓰는 키워드입니다.
- block-scope를 가집니다.
: {} 안에서 선언하면 {} 안에서만 쓸 수 있습니다.
- 재선언은 불가능, 재할당은 가능
// 재할당은 가능!
let cat_name = 'perl';
cat_name = '펄이';
// 재선언은 오류!
let cat_name = 'perl';
let cat_name = '펄이';
3) const
- 자바스크립트에서 상수를 생성 할 때 쓰는 키워드
- block-scope를 가집니다.
: {} 안에서 선언하면 {} 안에서만 쓸 수 있습니다.
- 재선언은 불가, 재할당도 불가 (=> 선언과 동시에 할당 합니다.)
// 재할당 오류!
const cat_name = 'perl';
cat_name = '펄이';
// 재선언도 오류!
const cat_name = 'perl';
const cat_name = '펄이';
// 선언과 동시에 할당 되기 때문에 값을 안줘도 오류가 납니다.
// declare!
const cat_name;
4) TDZ (Temporal Dead Zone) = 일시적 사각지대
Q. let과 const도 호이스팅이 될까??
A. let, const도 호이스팅이 됩니다, 스코프에 진입 할 때 변수를 만들고, TDZ가 생성 되지만 코드 실행이(=실행 컨텍스트가) 변수가 있는 실제 위치에 도달 할 때까지 엑세스를 못할 뿐!
Q. 왜 에러가 날까? 호이스팅이 안 된 걸까?
A. 호이스팅(=선언 끌어 올리기)은 됩니다! 다만, 선언한 후, 초기화 단계에서 메모리에 공간을 확보하는데, 선언을 호이스팅해도 초기화 전까지 메모리에 공간이 없죠! 그래서 변수를 참조할 수 없기 때문입니다. 이걸 TDZ라고 해요!
2. 자료형
👉 자바스크립트는 8가지 기본 자료형을 지원합니다!
**객체를 제외한 나머지 7가지를 원시형(primitive type)**이라고 불러요.
typeof 연산자로 자료형을 알아낼 수 있어요. 🙂
- 정수, 부동 소수점을 저장하는 숫자형: -(2^53-1) ~ (2^53-1)까지 지원
- 아주 큰 숫자를 저장하는 BigInt형
- 문자열을 저장하는 문자형
- 논리 값 (true/false. boolean형)
- 값이 할당되지 않음을 나타내는 독립 자료형 undefined
- 값이 존재하지 않음을 나타내는 독립 자료형 null
- 복잡한 자료구조를 저장하는 데 쓰는 객체형
- 고유 식별자를 만들 때 쓰는 심볼형
💡 [알아두면 더 좋은 Tip: 엄격 모드]
자바스크립트는 엄청 많은 버전이 있습니다!
우리가 들어본 ES6도 사실 자바스크립트의 한 버전일 뿐입니다.
(보통 이야기하는 하위 버전 자바스크립트는 ES3, 최신이다! 모던이다! 하면 ES6 이상을 가리키죠!)
자바스크립트는 하위 호환성에 도른 언어라, 코드를 읽을 때 모던한 방식보다는 하위 호환에 초점을 맞춰 동작합니다. 최신 기능이라기에 써봤는데, 오류를 뿜어낼 수 있단 소리입니다. 😢
그럴 때 쓰는 게 엄격 모드 use strict입니다.
'use strict;'를 스크립트 최상단에 써주면 모던 자바스크립트에서 지원하는 모든 기능을 활성화해줍니다!
3. 객체
1) 객체란?
- 오직 한 타입의 데이터만 담을 수 있는 원시형과 달리, 다양한 데이터를 담을 수 있습니다.
- key로 구분된 데이터 집합, 복잡한 개체를 저장할 수 있다.
- {...} ← 중괄호 안에 여러 쌍의 프로퍼티를 넣을 수 있다.
- 프로퍼티는 **key : value**로 구성
key에는 문자형, value에는 모든 자료형이 들어갈 수 있음
// 객체 생성자로 만들기
let cat = new Object();
// 객체 리터럴로 만들기
// 중괄호로 객체를 선언하는 걸 리터럴이라고 하는데, 객체 선언할 때 주로 씁니다!
let cat = {};
2) 상수는 재할당이 안된다고 했지만...
- const로 선언된 객체는 수정될 수 있어요. 😖 (← 아찔한 여러분,,)
- const로 선언된 객체는 객체에 대한 참조를 변경하지 못한다는 것을 의미합니다!
- 즉, 객체의 프로퍼티는 보호되지 않아요!
// my_cat이라는 상수를 만들었어요!
const my_cat = {
name: "perl",
status: "좀 언짢음",
}
my_cat.name = "펄이";
console.log(my_cat) // 고양이 이름이 바뀌었죠!
// 여기에선 에러가 날거예요. 프로퍼티는 변경이 되지만, 객체 자체를 제할당할 순 없거든요!
my_cat = {name: "perl2", status: "많이 언짢음"};
4. 함수
💡 자바스크립트는 함수를 특별한 값 취급을 해요. 자바스크립트는 ()가 있으면 함수를 실행하고 ()가 없으면 함수를 문자형으로 바꿔 출력하기도 서슴치 않거든요. (함수를 값으로 취급하는거죠!) 이걸 응용하면, 함수를 복사할 수 있고, 또 매개변수처럼 전달할 수 있어요. (소근)
- 함수는 기본적으로 undefined를 반환해요. return으로 어떤 값을 넘겨주지 않는다면요!
1) 함수 선언문과 함수 표현식
- 함수 선언문
// 이렇게 생긴 게 함수 선언문 방식으로 함수를 만든 거예요.
function cat() {
console.log('perl');
}
- 함수 표현식
// 이렇게 생긴 게 함수 표현식을 사용해 함수를 만든 거예요.
let cat = function() {
console.log('perl');
}
// 물논 화살표 함수로 써도 됩니다.
// 다만 주의하실 점! 화살표 함수는 함수 표현식의 단축형이라는 거! 주의하세요! :)
let cat2 = () => {
console.log('perl2');
}
- 함수 선언문 vs 함수 표현식
- 함수 선언문으로 함수를 생성하면 독립된 구문으로 존재
- 함수 표현식으로 함수를 생성하면 함수가 표현식의 일부로 존재
- 함수 선언문은 코드 블록이 실행되기 전에 미리 처리되어 블록 내 어디서든 사용할 수 있다.
- 함수 표현식은 실행 컨텍스트가 표현식에 닿으면 만들어진다. (변수처럼 처리되는 거죠!)
2) 지역 변수와 외부 변수
- 지역 변수
- 함수 내에서 선언한 변수
- 함수 내에서만 접근 가능
- 외부 변수(global 변수라고도 합니다.)
- 함수 외부에서 선언한 변수
- 함수 내에서도 접근할 수 있다.
- 함수 내부에 같은 이름을 가진 지역 변수가 있으면 사용할 수 없다.
let a = 'a'; let b = 'b'; let c = 'outter!'; const abc = () => { let b = 'inner!'; c = 'c'; let d = 'd'; console.log(a, b, c, d); } console.log(a, b, c, d); // a, b, outter, undefined abc(); // a, inner, c, d console.log(a, b, c, d); // a, b, c, undefined
3) 콜백 함수
👉 함수를 값처럼 전달할 때, 인수로 넘겨주는 함수를 콜백 함수라고 해요!
const playWithCat = (cat, action) => {
action(cat);
}
const useBall = (cat) => {
alert(cat+"과 공으로 놀아줍니다.");
}
//playWithCat 함수에 넘겨주는 useBall 함수가 콜백 함수입니다!
playWithCat("perl", useBall);
5. Prototype
1) 자바스크립트와 클래스 기반 객체 지향 언어
[주의!]
자바스크립트는 동적 언어이고 클래스가 없는 언어예요.
클래스 기반 언어를 사용하다 자바스크립트를 접하면 특히 혼란스러워하는 부분이죠!
앗? 분명 기초 강의에서는 클래스를 배웠는데...?
→ 네! 그 클래스는 ES2015(ES6)부터 지원하는 키워드입니다!
클래스 기반 언어가 말하는 클래스를 자바스크립트가 흉내낸 것 뿐이에요!
그럼 자바스크립트는 정확히 뭐지?
자바스크립트는 프로토타입 기반 동적 언어입니다. 🙂
- 객체 생성 방법이 다릅니다.
[클래스 기반]
ex) java, c++, ...
객체 생성 전에 클래스를 정의하고 이를 통해 객체(인스턴스)를 생성
[자바스크립트]
클래스 없이 객체를 생성(리터럴과 생성자)
2) 프로토타입이란?
자바스크립트의 모든 객체는 자신의 부모 객체와 연결되어 있어요.
좀 더 정확히는 부모 객체의 원형하고요!(부모 객체의 프로토타입)
마치 객체 지향에서의 상속 개념처럼 부모 객체의 프로퍼티나 메소드를 상속받아 쓸 수 있고요.
(실제로는 상속보다 위임에 가깝다고 하지만, 통상적으로 상속한다고 표현해요.)
이런 부모 객체를 프로토타입 객체, 혹은 그냥 프로토타입이라고 부릅니다. 🙂
그리고 부모 객체를 참조하는 걸 두고 프로토타입 링크라고 해요.
// animal이라는 객체를 하나 만들었습니다!
let animal = {
leg: 4,
legCount() {
console.log(this.leg); // this는 animal을 의미합니다.
}
};
// 또 다른 객체 cat을 만들었고요!
// animal을 프로토타입 상속 받아올 거예요. (__proto__를 씁니다.)
let cat = {
__proto__:animal, // cat의 프로토타입은 animal!
cute: true,
};
// 프로토타입을 설정해주어서 cat은 animal의 메소드와 프로퍼티를 사용할 수 있어요.
cat.legCount();
console.log(cat.leg);
// cat만 가지고 있는 프로퍼티도 있고요!
console.log(cat.cute);
// animal은 cat의 속성을 가져올 수 없어요!
console.log(animal.cute);
- 위 예제에서 animal은 cat의 프로토타입 객체입니다. cat의 프로토타입은 animal이라고도 해요!
- cat.legCount()에서 실행되는 legCount는 animal에서 상속된 메소드예요.
- → animal의 메소드와 속성이 복사되어 cat에 들어가는 게 아닙니다!
- animal을 상속 받은 cat, cat을 상속받은 다른 객체를 만들 수도 있을거예요.
- 순환 참조는 되지 않아요! (animal은 cat을 상속받은 객체를 상속할 수 없어요!)
- → 이런 식으로 상속이 쭉쭉 내려가는 걸 프로토타입 체인이라고 불러요.
[프로토타입 객체와 프로토타입 링크]
위 예제에서 우리는 두 가지 프로토타입을 배웠어요.
하나는 프로토타입 객체, 또 하나는 프로토타입 링크([[Prototype]](숨김 프로퍼티)가 참조하는 값과 __proto__ )예요.
아직까지 면접 질문에 자주 출몰하고, 프로토타입 링크를 이야기할 때 __proto__ 를 써서 이야기 하지만,
__proto__ 를 사용하는 방식은 구식이에요. 😖 (deprecated되었거든요.(링크→))
면접을 대비한다면 위 예제처럼 __proto__ 로 직접 접근하는 방식을 알아두는 편이 좋지만,
그게 아니라면 가급적 Object.getPrototypeOf()를 이용해 참조하고,
프로토타입 체인에 연결할 때는 Object.create() 를 이용해 연결합시다!
Prototype 결론
1. 객체는 함수를 사용해서 만들어 진다
2. 그 객체는 함수의 프로토타입 객체를 복사해서 생성한다.
'항해 중 > 5주차 리액트 심화반' 카테고리의 다른 글
2주차 - 웹 저장소(feat. 토큰) (0) | 2021.11.30 |
---|---|
2주차 - 토큰 기반 인증(OAuth 2.0, JWT) (0) | 2021.11.30 |
2주차 - Promise (0) | 2021.11.30 |
1주차 - 프로젝트 생성, 최소 단위 컴포넌트 만들기, 숙제 (0) | 2021.11.29 |
5주차 개인 과제 (0) | 2021.11.29 |
댓글