시하언니, 자연언니, 정화언니와 함께하는 일주일만에 중급강좌 뽀개기!
기존 var
사용, ES6 부터 let
과 const
가 추가되었다.
var
는 한번 선언된 변수를 다시 선언할 수 있다.
console.log(name); // undefined
var name = 'jubby';
또한 선언하기 전에 사용할 수 있다.
var
로 선언한 모든 변수는 코드가 실제로 이동하진 않지만 최상위로 끌어올려진 것 처럼 동작하기 때문이다. 이것을 호이스팅(hoisting)
이라고 한다.
var name;
console.log(name); // undefined
name = 'jubby'; // 할당
이때 콘솔에 undefined
가 나오는 이유는?
선언은 호이스팅이 되지만, 할당은 호이스팅 되지 않기 때문이다. name이란 변수만 올려주고, 'jubby'라는 값은 그 자리에 있기 때문이다.
let
은 재선언이 불가능하다.
let name = 'jubby';
console.log(name); // jubby
let name = 'ohwa';
console.log(name); // error!
let
은 선언하기 전에 사용하면 에러가 발생한다.
console.log(name); //ReferenceError
let name = 'jubby';
하지만 let
도 사실 호이스팅이 되는 것이다.
호이스팅?
스코프 내부 어디서든 변수 선언은 최상위에 선언된 것처럼 행동
하지만 에러가 발생하는 이유는?
Temporal Dead Zone
즉 TDZ
때문이다.
TDZ 영역에 있는 변수들은 시용할 수 없다. let
과 const
는 이 TDZ
의 영향을 받아, 할당을 하기 전에는 사용할 수 없다.
이는 코드를 예측 가능하게 하고, 잠재적인 버그를 줄일 수 있도록 해준다.
let age = 30;
function showAge() {
console.log(age); // Error, 여기서 age 변수가 호이스팅을 일으킨다.
let age = 20;
}
showAge();
호이스팅은 스코프 단위로 일을 한다.
위 코드에서 스코프 부분은 showAge()
함수 부분이다.
var
는 선언과 초기화가 동시에 진행된다. 그래서 할당 전에 호출하면 error
를 내지 않고 undefined
가 나오는 것이다.
let
은 선언단계와 초기화 단계가 분리되어서 진행된다. 호이스팅 되면서 선언 단계가 이루어지지만, 초기화 단계는 실제 코드에 도달했을때 진행되면서 레퍼런스 에러가 발생한다.
const
는 선언과 할당이 동시에 된다.
let name;
name = 'jubby';
var age;
age = 25;
const gender; // error
gender = 'male';
gender 변수를 선언하면서 할당을 하지 않았기 때문에 에러가 발생하게 된다.
var
: 함수 스코프(function-scoped)
let
: 블록 스코프(block-scoped)
const
: 블록 스코프(block-scoped)
블록 스코프?
모든 코드 블록내에서 선언된 변수는 코드 블록(함수, if문, for문, while문, try/catch문)내에서 유효하며 외부에서는 접근할 수 없다는 의미
/* 블록 스코프 */
const age = 30;
if(age>19) {
var txt = '성인';
}
console.log(txt); // '성인'
/* 함수 스코프 */
function add(num1, num2) {
var result = num1 + num2;
}
add(2,3);
console.log(result); // error
객체를 만드는 방법은 '객체 생성자' 와 '객체 리터럴' 방법 2가지가 있다.
let user = {
name : 'jubby',
age : 25,
}
//추가
user.isAdmin = true;
user["likes birds"] = true;
//삭제
delete user.age;
delete user["likes birds"];
function User(name, age) {
this.name = name;
this.age = age;
}
let user1 = new User('jubby', 25);
let user2 = new User('ohwa', 28);
let user3 = new User('sha', 28);
new 연산자를 사용해서 호출하고 함수명의 첫글자는 대문자로 표현한다.
/* 생성자 함수 작동 순서*/
function User(name, age) {
// this = {}
this.name = name;
this.age = age;
// return this;
}
new 함수명();
new 함수명();
을 실행하면 먼저 빈 객체를 만들고 this
에 할당한다. this
의 프로퍼티를 추가하고, 마지막으로 this
를 반환한다.
/* 메소드 추가*/
function User(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name); //여기에서 this = user5
}
}
let user5 = new User('Nature', 26);
user5.sayName(); // 'Nature'
function Item(title, price) {
// this = {};
this.title = title;
this.price = price;
this.showPrice = function(){
console.log(`가격은 ${price}원 입니다.`);
// return this;
}
const item1 = new Item('인형', 2000);
const item2 = new Item('가방', 3000);
const item3 = new Item('지갑', 9000);
console.log(item1, item2, item3);
item3.showPrice();
실행결과
Item {title: "인형", price: 2000, showPrice: f}
Item {title: "가방", price: 3000, showPrice: f}
Item {title: "지갑", price: 9000, showPrice: f}
가격은 9000원 입니다.
일반
let a = 'age';
const user = {
name: 'jubby',
age: 25
}
계산된 프로퍼티
let a = 'age';
const user = {
name: 'jubby',
[a] : 25 // 위의 'age' 값이 [a]로 들어온다.
}
const user = {
[1+4] : 5,
["안녕"+"하세요"] : "Hello"
}
> user
{5: 5, 안녕하세요: "Hello"}
Object.assign(): 객체 복제
const user = {
name : 'jubby',
age : 25
}
const cloneUser = user; // X
객체 자체가 들어가는 것이 아닌, 객체가 저장되어 있는 메모리 주소인 객체에 대한 참조값이 저장된다. 하나의 객체를 두 변수가 접근하고 있게 된다. 그래서 cloneUser의 값을 변경하면 user의 값도 변경된다.
const user = {
name : 'jubby',
age : 25
}
const cloneUser = user; // X
const newUser = Object.assign({},
user);
빈 객체는 초기화며, 두번째 매개변수로 들어온 객체들이 초기값에 병합된다.
{} + { name: 'jubby', age: 25 }
Object.assign({ gender : 'female'}, user);
geder : 'female',
name : 'jubby',
age : 25,
병합하는 데 키가 같다면 덮어쓰게 된다.
Object.assign({ name : 'ohwa'}, user);
name : 'ohwa',
age : 25,
두개 이상의 객체를 합칠 수 있다.
const user = {
name : 'jubby'
}
const info1 = {
age : 25,
}
const info2 = {
gender : 'female',
}
Object.assign(user, info1, info2); // user에 info1, info2를 병합한다.
Object.keys(): 키 배열 반환
const user = {
name : 'jubby',
age : 25,
gender : 'female',
}
Object.keys(user); // ["name", "age", "gender"]
Object.values(): 값 배열 반환
const user = {
name : 'jubby',
age : 25,
gender : 'female',
}
Object.values(user); // ["jubby", 25, "female"]
Object.entries(): 키/값 배열 반환
const user = {
name : 'jubby',
age : 25,
gender : 'female',
}
Object.entries(user);
// [
// ["name", "jubby"],
// ["age", 25],
// ["gender", "female"]
// ]
Object.fromEntries(): 키/값 배열을 객체로
const arr =
[
["name", "jubby"],
["age", 25],
["gender", "female"]
];
Object.fromEntries(user);
// {
// name : 'jubby',
// age : 30,
// gender : 'female',
// }
예제
let n = "name";
let a = "age";
const user = {
[n]: "jubby",
[a]: 25,
[1+4]: 5,
};
console.log(user); // {5: 5, name: "jubby", age: 25}
function makeObj(key, val) {
return {
[key]: val
}
}
const obj = makeObj("나이", 25);
console.log(obj); // {나이: 25}
const obj = makeObj("성별", "female");
console.log(obj); // {성별: female}
const user = {
name : 'jubby',
age : 25,
};
const user2 = user;
user2.name = "ohwa";
console.log(user); //{name: "ohwa", age: 25}
console.log(user2); //{name: "ohwa", age: 25}
const user = {
name : 'jubby',
age : 25,
};
const user2 = Object.assign({},user);
user2.name = "ohwa";
console.log(user); //{name: "jubby", age: 25}
console.log(user2); //{name: "ohwa", age: 25}
const result = Object.keys(user);
console.log(result); // [ "name", "age" ]
const result2 = Object.values(user);
console.log(result2); // [ "jubby", 25 ]
const result3 = Object.entries(user);
console.log(result3);
// [ ["name", "jubby"], ["age", 25] ]
let arr = [
['mon', '월'],
['tue', '화']
]
const result = Object.fromEntries(arr);
console.log(result); // { mon: "월", tue: "화" }