[자바스크립트] 벨로퍼트와 함께하는 모던 자바스크립트

2020. 7. 18. 17:34TIL/자바스크립트

나는 쭉 공부해오던 자바가 아닌, 자바스크립트로 웹 풀스택 과정을 진행하는

부스트캠프 2020에 합격하였다. 생활코딩 강의를 통해 정말 기본이 되는 내용만 공부했던 나는

좀 더 본격적으로 자바스크립트 공부를 해야 하는 상황에 놓였다.

짧은 기간안에 자바스크립트에 대한 속성 강의가 필요했던 나는 많은 사람들이 추천해준

벨로퍼트님의 자료들을 공부해보기로 했다.

양이 많지 않고, 웹페이지를 통해 쉽게 접근할 수 있기 때문에 공부하기에 좋았던 것 같다.

공부한 내용을 전부 적기에는 시간이 많지 않았기 때문에, 공부 과정 중 새롭게 느껴진 부분이나

헷갈리는 부분에 대해서만 정리를 하려고 한다.

1. 비교연산자

아주 기초적인 문법을 배우면서 자바와 다른점을 느낀 부분은 역시 비교 연산자였다. 자바의 경우 타입이 다르면 코드 작성 과정에서 에러를 감지할 수 있지만, 자바스크립트는 이와는 달랐다. 두 피연산자가 같은지를 비교하기 위해서 '==='와 '=='이 사용될 수 있었는데, ' == ' 의 경우 타입을 고려하지 않고 비교하기 때문에 실수의 여지가 많다고 한다. 즉 1 == '1' 이 true를 반환하는 것이다. 하나는 숫자고, 하나는 문자열인데... 자바가 다시 하고 싶다... '=='을 통해 비교를 하는 경우 실수의 여지가 많아지기 때문에 되도록 '==='을 통해 비교하는 것을 권장해 주셨다. ( '==='과 '!=='은 내용물을 비교하기 이전에 타입이 다르면 무조건 false를 반환해준다.)

2. null과 undefined

이 차이에 대해서는 내가 생각을 해본 적이 없는 것 같다. 두 개 모두 의미는 어떠한 값이 '없다'라는 것인데, null의 경우 일부러 값이 없도록 설정해주었을 때이고, undefined는 아무런 값도 설정해주지 않아서 값이 없다는 의미라고 한다.

3. const와 let

자바를 하다가 온 나에게 자바스크립트의 변수 선언 과정은 그야말로 '?'였다. 타입을 정해주지 않고 var, const, let과 같이 알 수 없는 키워드가 붙어있었기 때문이다. 더 깊게 배우면 어떠한 차이점이 있을지 모르지만, 기초단계에서는 let은 변수 선언 시에, const는 상수 선언시에 사용한다고 한다. 그리고 var는 let과 같은 역할이지만 차이점은 변수 이름을 동일하게 여러 개 만들 수 있다는 것이다. var사용은 최대한 지양하고 const와 let으로 선언한다는 것만 알아두고 일단 넘어가야겠다.

+ 자바스크립트는 값을 대입하는 순간에 그 변수의 타입이 결정된다고 생각하면 되는 것인지... 모르겠다...

4. 문자열 조합

자바에서와 마찬가지로 두 문자열을 합치기 위해서는 concat함수를 사용하거나 ' + '를 통해 조합할 수 있다. 하지만 이것을 좀 더 쉽게(?) 할 수 있도록 ES6에서는 템플릿 리터럴이라는 문법을 지원한다. 문자열 조합을 위해 $ {변수}를 사용하는 것이다. 예시 코드만으로 금방 이해할 수 있을 것이다.

function hello(name) {
  console.log(`Hello, ${name}!`);
}
hello('minseob');

여기서 잘 보면, 템플릿 리터럴 문법을 사용한 따옴표가 일반적으로 사용하던 작은따옴표가 아닌 백틱인것을 볼 수 있다... (삽질포인트) 맥북에서는 영문 상태일 경우 ₩를 누르면 백틱이 출력된다. (한글 상태일 경우 option + ₩)

5. 화살표 함수

4번에서처럼 function 함수명(parameter){} 형태로 함수를 만들 수도 있지만, 화살표 문법을 통해서도 함수를 만들 수 있다. 위의 함수에 적용하여 표현해보면 아래와 같다.

const hello = (name) => {
    console.log(`hello ! ${name}!!`);
};

변수명 = ( 매개변수들 ) => { } ; 를 통해 함수를 만들 수 있다.

기본적으로 같은 의미를 갖지만, function을 통해 만드는 함수와 => 를 통해 만드는 함수에서 this의 의미가 서로 다르다고 한다.

6. 객체

자바스크립트에서 객체에 값을 넣을 때는 '키 : 밸류(value)'의 형태로 넣어주어야 한다. 이때 키 값에는 공백이 없어야 하는데, 만약 공백을 넣어주고 싶다면 ' ' 안에 문자열의 형태로 키값을 설정해주면 된다. 특이했던 점은 함수의 파라미터로 객체를 넘겨줄 때였는데, 처음 보는 개념은 객체 비구조화 할당이었다. 객체 구조 분해라고도 불리는 이 문법을 통해서, 객체 내부의 정보에 더 쉽게 접근이 가능해져서 코드가 훨씬 간결해지는 것을 볼 수 있었다. 예시 코드를 보면 이해가 쉽게 될 것이다.

function printHero(hero){
  const statement = `${hero.name}(${hero.alias}) 를 연기한 사람은 ${hero.actor}이다.`
  console.log(statement);
}


const ironman = {
  name : '토니 스타크',
  alias : '아이언맨',
  actor : '로다주'

}

printHero(ironman);

위의 코드에서, hero의 정보에 접근하기 위해 hero.name, hero. alias, hero.actor 이런 식으로 접근하는데, 객체 구조 분해 문법을 사용한다면 아래와 같이 접근할 수 있다.

function printHero(hero){
  const {name,alias,actor} = hero;
  const statement = `${name}(${alias}) 를 연기한 사람은 ${actor}이다.`
  console.log(statement);
}


const ironman = {
  name : '토니 스타크',
  alias : '아이언맨',
  actor : '로다주'

}

printHero(ironman);

const {name, alias, actor} = hero가 의미하는 것은 hero안에 있는 name, alias, actor라는 정보를 새로운 변수에 담아주는 작업을 하는 것이다. 따라서 이후에는 'hero.'을 붙이지 않아도 해당 정보에 접근할 수 있게 된다.

이것을 조금 더 간결하게 만들면 아래와 같이 파라미터로 넘길 때 정보를 상수화 시켜서 넘겨줄 수 있다.

function printHero({name, alias, actor}){
  const statement = `${name}(${alias}) 를 연기한 사람은 ${actor}이다.`
  console.log(statement);
}


const ironman = {
  name : '토니 스타크',
  alias : '아이언맨',
  actor : '로다주'

}

printHero(ironman);

7. 객체 안에 함수 넣기

객체 안에는 함수를 넣을 수도 있는데, 이때 주의할 점은 function 키워드를 통해서만 넣어줄 수 있다. 즉, => 화살표를 이용해 함수를 넣어줄 수는 없다. 그 이유는, 위에서 언급했던 것처럼 두 함수에서의 this의 의미가 서로 다르기 때문이다.

const ironman = {
  name : '토니스타크',
  alias : '아이언맨',
  actor : '로다주',
  introduce : function introduce(){
    console.log(this.name + ' ' + this.alias+ ' ' + this.actor);
  }
}

console.log(ironman.introduce());

이와 같이 객체 안에 들어간 함수에서의 this는 해당 함수가 들어있는 객체를 가리킨다. 하지만 화살표를 통해 만든 함수는 그렇지 않기 때문에, 객체 안에서 사용할 수 없다. 한편, 객체 안의 함수를 선언할 때는 함수의 이름을 넣어주지 않아도 되는데 , 함수 호출을 위해서는 key값을 통해 호출하기 때문이다. 따라서 value에 해당하는 함수명은 있어도 되고 없어도 된다.

8. getter와 setter 

자바를 공부할 당시 getter와 setter함수의 사용을 지양해야 한다는 내용의 정리를 한 적이 있다. (getter메서드 사용을 지양하자). 아마 이 내용은 언어에 관계없이 공통된 내용일 것이다. 그런데, 자바스크립트에서 getter와 setter를 사용하는 이유는 내가 아는 선에서는 객체의 정보에 직접적으로 접근하는 것을 막는 것이다. 자바에서는 같은 이유로 getter의 사용을 지양하는데 말이다... 아마 내가 어느 부분에선가 개념을 혼동하고 있는 것 같지만, 우선 자바스크립트에서는 변수의 이름에 직접적으로 접근하지 못하도록 하기 위해 getter와 setter 함수를 만든다. 자바에서는 그냥 메소드 이름을 get ~ , set ~으로 지으면 그것이 getter와 setter의 역할을 했는데, 자바스크립트에서는 getter와 setter역할을 하는 메소드를 선언하기 위한 특별한 form이 있었다. 벨로퍼트님의 코드를 예시로 분석해 보겠다.

const numbers = {
  _a: 1,
  _b: 2,
  sum: 3,
  calculate() {
    console.log('calculate');
    this.sum = this._a + this._b;
  },
  get a() {
    return this._a;
  },
  get b() {
    return this._b;
  },
  set a(value) {
    console.log('a가 바뀝니다.');
    this._a = value;
    this.calculate();
  },
  set b(value) {
    console.log('b가 바뀝니다.');
    this._b = value;
    this.calculate();
  }
};

console.log(numbers.sum);
numbers.a = 5;
numbers.b = 7;
numbers.a = 9;
console.log(numbers.sum);
console.log(numbers.sum);
console.log(numbers.sum);

위와 같이 getter역할을 하는 메소드의 앞에 get을 붙이고 setter역할을 하는 메소드의 앞에 set을 붙인다. 코드를 살펴보면 numbers라는 객체에는 _a, _b라는 이름의 정보가 들어있지만 실제로 해당 값을 조회하거나 변경할 때는 a, b로 접근한다는 것을 볼 수 있다. set으로 설정한 메소드는 = 뒤의 값을 매개변수로 인식해서 실행되게 된다.