let과 const는 최근에 추가된 문법이며, 이전에는 var를 사용했습니다.
let과 var는 거의 대부분의 경우에 같은 역할을 합니다.
var name1 ='mike';
console.log(name); // mike
var name1 = 'michael';
console.log(name); // michael
let name2 ='mike';
console.log(name); // mike
let name2 = 'michael';
console.log(name); // 에러 발생
차이점은 var는 한번 선언된 변수를 다시 선언할 수 있습니다.
let의 경우에는 다시 선언할 경우 error가 발생합니다.
var name1;
console.log(name1); // undefined 초기화
name1 = 'mike';
console.log(name2); // error , TDZ 할당전 사용 불가
let name2 = 'mocha';
var는 선언하기 전에 사용할 수 있습니다 (호이스팅)
이 때 선언은 호이스팅 되지만 할당은 호이스팅되지 않기 때문에 undefined를 반환합니다. let도 호이스팅 되지만 error를 발생합니다.
그 이유는 (Temporal Dead Zone)TDZ 때문입니다. let과 const는 TDZ의 영향을 받아 선언 전에 사용할 수 없습니다.
let age = 30;
fuction showAge() {
cosole.log(age); // error 발생, TDZ
let age = 20; // 호이스팅 -> 스코프는 함수
}
위는 let이 호이스팅 된다는 것을 모여주는 코드 입니다.
만약 호이스팅이 되지 않는다면, 함수 외부에서 할당한 30이 log에 찍히겠지만, 호이스팅과 TDZ에 인해 error를 발생할 것 입니다.
호이스팅 : 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것 처럼 동작하는 것
var
1. 선언 및 초기화 단계 (선언과 동시에 undefined로 초기화)
2. 할당 단계
let
1. 선언 단계 (호이스팅)
2. 초기화 단계
3. 할당 단계
const
1. 선언+초기화+할당
(let 과 var는 선언만 해놓고 나중에 변수를 넣을 수 있지만 const는 선언과 동시에 할당을 해야합니다.)
let name;
name = 'mike';
var age;
age = 33;
const gender; // 선언 때 할당을 안해서 error 발생
gender = 'male';
var : 함수 스코프 (function scoped)
let, const : 블록 스코프 (block scoped)
함수, if문, for문, while문, try/catch문 등
function add() {
// block level scoped
}
if() {
// block level scoped
}
블록 스코프란 코드블럭 내부에서 선언된 변수는 해당 코드블럭 안에서만 동작 할 수 있는 것을 뜻합니다.
const age = 33;
if)(age>19){
var txt = '성인';
}
console.log(txt); // '성인' var로 선언했기 때문에 가능
function add (num1, num2){
var result = num1 + num2;
}
add(2,3);
console.log(result);
// error 발생 :
// var가 유일하게 벗어날 수 없는 스코프가 있습니다. 바로 함수 스코프 입니다.
let user = {
name : 'mike';
age : 30,
} // 객체를 만드는 방법
위의 코드는 객체를 만드는 기본적인 방법입니다.
위와 같은 객체가 여러개가 필요하다면? 사용하는 것이 생성자 함수 입니다.
fuction User(name, age){
// User 에서 첫글자가 대문자 인 것은 생성자 함수임을 알려주는 장치임.
this.name = name;
this.age = age;
}
let user1 = new User('mike',30);
let user2 = new User('jun',14);
let user3 = new User('ho',18);
// new 연산자를 사용해서 호출해 줍니다.
위의 코드로 순식산에 서로 다른 3개의 객체를 만들어 줍니다.
fuction User(name, age){
// this = {}
this.name = name;
this.age = age;
// return this;
}
new User();
new로 함수를 호출하면 발생하는 일
1. 함수 내부에서 this 라는 객체를 만듭니다 (코드에는 없지만)
2. 코드에 있는 값들을 this에 저장합니다. (this.name, this.age)
3. this를 반환합니다. (코드에는 없지만 ^^)
빠르고 일관성있는 여러개의 객체를 만들 수 있는 방법입니다.
객체 안에 메소드를 추가할때도 같은 방식으로 동작합니다.
let a = 'age';
const user = {
name = 'mike';
[a] : 30 // age : 30, computed property
}
function makeObj(key, val){
return {
[key] : val,
}
}
const obj = makeObj("나이",33);
// "나이"가 키가 되고, 33은 값이됩니다. 어떤 것이 키가 될지 모를때 유용
console.log(obj);
객체에서 사용할 수 있는 메소드 리스트
const user = {
name : 'mike';
age : 33,
}
const newUser = Object.assign({},user); // 객체 복사
newUser.name = 'top';
console.log(newUser.name); // top -> 변경 완료
console.log(user.name); // mike -> 기존 객체는 값 유지
Object.assign()는 객체의 값을 복사해서 "새로운 객체"를 만들어 줍니다. 위의 코드에서 보면 name 값을 바꿔도 기존 객체에는 영향을 주지 않는 것을 볼 수 있습니다.
const user = {
name : 'mike'
}
const info1 = {
age : 33
}
const info2 = {
gender : 'male'
}
Object.assign(user,info1,info2)
위의 코드 처럼 여러개의 객체를 한번에 합쳐서 새로운 객체를 만들 수도 있습니다.
const user = {
name : 'mike',
age : 30,
gender : 'female',
}
Object.keys(user);
// ["name","age","gender"]
Object.values(user);
// ["mike",30,"female"]
Object.entries(user);
//
[
["name","mike"],
["age",30],
["gender","female"]
]
//
Object.keys 는 객체의 키를 배열로 만들어서 반환 합니다.
Object.values 는 객체의 값을 배열로 만들어서 반환 합니다.
Object.entries 는 객체의 키와 값을 배열로 만들어서 반환
Object.fromEntries 는 키/값 배열을 객체로 변환 (entries와 반대)
지금까지 객체의 프로퍼티 키는 문자열로 만들었습니다. 하지만 문자열 말고 가능한 것이 있습니다. 그것이 바로 심볼입니다.
//유일성 보장의 예시
const sym1 = Symbol();
const sym2 = Symbol('foo');
const sym3 = Symbol('foo');
// 3개의 심볼을 만들었습니다. sym2와 sym3는 보기에는 같아보이죠
Symbol('foo') === Symbol('foo') // false
// 유일성 보장으로 서로 다릅 값이라는 것 입니다.
심볼은 언제 사용할까요? 바로 유일한 식별자로 사용할 때 사용합니다.
주 역할이 유일성 보장이라고 할 수 있습니다.
// 이미 존재 or 다른 팀원이 만들 객체
const user = {
name : 'mike',
age : 30,
}
// 내가 작업하는 부분
// user.showName = fuction() {}; -> 이렇게하면 꼬이게 되겠죠
const showName = Symbol('show name'); // 심볼을 선언하는 방법
user[showName] = fuction() {
console.log(this.name);
};
user[showName]
// 사용자가 접속하면 보는 메시지
for(let key in user){
console.log(`his ${key} is ${user[key]}.`);
}
유일성을 갖는 다는 것이 왜 중요할까요?
협업을 할때 각자가 컨트롤하는 객체가 있을 수 있고, 해당 이름을
symbol.for() : 전역 심볼
const id1 = Symbol.for('id');
const id2 = Symbol.for('id');
id1 === id2; // true
Symbol.keyFor(id1) // 'id'
const pw = Symbol('pw 입니다.');
id.description; // "pw 입니다."
전역 심볼의 경우 생성할 때 적어주었던 이름은 keyFor을 통해 알 수 있다.
전역 심볼이 아닐경우에는 description을 통해 할 수 있습니다.
const id = Symbol('id');
const user = {
name : 'mike',
age : 30,
[id] : 'myid',
}
Object.getOwnPropertySymbols(user); // [Symbol(id)]
Reflect.ownKeys(user); // ["name"],"age",Symbol(id)]
심볼을 완전 숨길 수는 없고 위의 코드처럼 확인할 수 있습니다.
심볼 쉬운 듯하지만 이해가 더욱 필요할 것 같습니다.