JavaScript - 변수, 호이스팅, TDZ, 스코프, 생성자, 객체

dev_jubby·2022년 10월 3일
0

JavaScript

목록 보기
1/6

시하언니, 자연언니, 정화언니와 함께하는 일주일만에 중급강좌 뽀개기!



📎 변수

기존 var 사용, ES6 부터 letconst가 추가되었다.


var

var는 한번 선언된 변수를 다시 선언할 수 있다.

console.log(name); // undefined
var name = 'jubby';

또한 선언하기 전에 사용할 수 있다.
var로 선언한 모든 변수는 코드가 실제로 이동하진 않지만 최상위로 끌어올려진 것 처럼 동작하기 때문이다. 이것을 호이스팅(hoisting) 이라고 한다.

var name; 
console.log(name); // undefined
name = 'jubby'; // 할당

이때 콘솔에 undefined가 나오는 이유는?

선언호이스팅이 되지만, 할당호이스팅 되지 않기 때문이다. name이란 변수만 올려주고, 'jubby'라는 값은 그 자리에 있기 때문이다.


let

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 ZoneTDZ 때문이다.
TDZ 영역에 있는 변수들은 시용할 수 없다. letconst는 이 TDZ의 영향을 받아, 할당을 하기 전에는 사용할 수 없다.

이는 코드를 예측 가능하게 하고, 잠재적인 버그를 줄일 수 있도록 해준다.

let age = 30;

function showAge() {
  console.log(age); // Error, 여기서 age 변수가 호이스팅을 일으킨다.
  
  let age = 20;
}

showAge();

호이스팅은 스코프 단위로 일을 한다.
위 코드에서 스코프 부분은 showAge() 함수 부분이다.

변수의 생성과정

  1. 선언 단계
  2. 초기화 단계
  3. 할당 단계

var는 선언과 초기화가 동시에 진행된다. 그래서 할당 전에 호출하면 error를 내지 않고 undefined가 나오는 것이다.

let은 선언단계와 초기화 단계가 분리되어서 진행된다. 호이스팅 되면서 선언 단계가 이루어지지만, 초기화 단계는 실제 코드에 도달했을때 진행되면서 레퍼런스 에러가 발생한다.

const는 선언과 할당이 동시에 된다.

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


📁 생성자 함수 (Intermediate Class)

객체를 만드는 방법은 '객체 생성자' 와 '객체 리터럴' 방법 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원 입니다.



📺 객체 메소드 (Object method), 계산된 프로퍼티(Computed property)


Computed Property

일반

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"}

Method

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: "화" }
profile
신입 개발자 쥬비의 기술 블로그 입니다.

0개의 댓글