Front End/JavaScript

Koans를 통해 알게 된 것들

Koans는 불교에서 유래된 단어로 결론을 내리기 전에 이게 왜 맞는지 깊게 고민한다는 의미라고 한다. 단순히 문제를 푸는 것이 아니라, 문제를 푸는 과정에서 왜 문제의 해답이 나왔는 지에 대해 되짚어보면서 깊이 이해하라는 뜻으로 받아들였다. 이번 Koans를 풀면서 알게 된 것들을 정리한다.

mocha, chai : 테스트 자동화

Koans는 mocha, chai 라는 프레임워크와 라이브러리를 사용해 우리가 푼 문제가 맞는지 틀린지 자동으로 실행하여 확인해준다. 이는 단순히 문제를 푸는 것을 넘어, 테스트를 자동화하여 개발할 때 유용하게 사용 할 수 있다.

코드를 테스트를 해야 하는 이유는 우리가 단순히 함수 하나를 구현하고 끝내지 않기 때문이다. 여러 함수를 사용하고 유기적으로 돌아가는 어플리케이션 제작을 목표로 하기 때문에, 하나의 오작동이나 오류가 side effect를 일으켜 앱 실행 전체에 문제를 끼칠 수 있다.

그래서 개발을 하면서 정상 작동을 하는지 재실행 하는 것을 넘어서서 다양한 조건으로 실행하여 실행 결과와 기대 결과를 비교해야 한다. 이 때 Mocha 라는 테스트 프레임워크와 chai라는 assertion(개발자가 반드시 참이어야 한다고 생각하는 사항을 표현한 논리식)을 제공하는 라이브러리를 활용하면 여러 실행 조건을 자동으로 테스트하여 실행 결과를 미리 확인할 수 있다.

const를 사용하는 이유

var 는 재선언을 해도 오류를 발생시키지 않을 뿐 더러 블록 스코프를 무시하기 때문에 지양해야 한다지만, let만 쓰는 것이 아닌 const (상수)를 선언하는 이유는 무엇일까?

const는 값의 재할당이 불가능하기 때문에 의도치 않은 값의 재할당을 방지한다. 물론 mutable한 참조 자료형은 메서드를 사용해 값을 변경할 수 있지만, 값 자체를 새로 할당하는 것을 미연에 방지해주기 때문에 필요에 따라 선언 방식을 적절히 사용해야된다.

함수 호이스팅(hoisting)

우리가 알고 있는 JavaScript는 위에서 아래로 순차적으로 읽어내려 간다고 알고 있다. 하지만 실제로 작성해보면 함수 호출식이 선언식보다 위에 있더라도 정상적으로 실행되는 것을 발견 할 수 있다.

JavaScript는 실행을 할 때 함수 선언식이 발견되면 강제로 끌어올려서 함수를 위쪽에 두고 위에서부터 아래로 읽어내린다. 이를 함수 호이스팅(hoisting) 이라 한다.

기본값 매개변수(default parameter)

함수에서 쓰이는 매개변수는 기본적으로 undefined 값을 가진다. 하지만 매개변수가 들어가는 곳에 등호=를 이용해 미리 매개변수의 기본 값을 설정할 수 있다. 만약 함수 호출 시 전달인자가 있다면 전달인자를 그대로 반영한다.

function defaultParameter(num = 5) {
	return num;
}

console.log(defultParameter()); // 5
console.log(defultParameter(10)); // 10

객체를 컨트롤하는 내장함수 Object

객체의 키나 값을 배열로 만들어주는 .keys() .values()

배열의 길이는 .length로 확인할 수 있다. 그렇다면 객체는? 객체는 .length 를 사용할 수 없다. 표현식부터가 키에 해당하는 값에 접근하는 것이기 때문이다. 하지만 간접적으로 우회하여 확인할 수 있는데, 내장함수인 Object 이다. Object.keys()는 객체 내의 키들을 모아 배열로 반환하고, Object.values()는 값을 모아 배열로 반환한다.

let obj = {
  0: 'a',
  1: 'b',
  2: 'c'
}

let objKeys = Object.keys(obj); // [0, 1, 2]
let objValues = Object.values(obj); // ['a', 'b', 'c']
let objLength = objKeys.length; // 3

객체를 복사할 때 사용하는 .assign(target, source)

객체의 복사는 spread 를 사용해 간단히 할 수 있지만, .assign() 으로도 가능하다. 단, 해당 메서드는 얕은 복사만 하게 되니 주의 요망.

객체의 얕은 복사와 깊은 복사

얕은 복사(Shallow Copy)

객체를 복사할 때 원래의 값과 복사된 값이 같은 참조를 가리키는 것을 뜻한다. 만약 객체 안에 객체가 있다면 내부의 객체는 같은 주소를 참조하게 된다. spread 문법이나 Object.assign()이 이에 해당한다.

깊은 복사(Deep Copy)

객체 내에 객체가 있더라도 원본과의 참조 주소가 완전히 끊어져 새로운 객체로 복사되는 것을 뜻한다. for문을 이용한 함수를 작성하거나 JSON.stringify(), 또는 라이브러리를 사용하면 가능하다.

this는 무엇일까?

this는 JavaScript의 예약어로, 자신이 속한 객체나 인스턴스를 가리키는 자기 참조 변수다. 따라서 객체 내부에서 this를 사용하면 해당 객체 자체를 참조한다. 만약 전역에서 this를 사용하면 런타임에 따라 브라우저는 window, Node.js는 global이 된다.

  • 단, 화살표 함수는 자신의 this가 존재하지 않는다.

전달인자를 유사배열로 만들어주는 arguments

함수 내에 arguments를 사용하면 받아온 전달인자를 배열과 유사한 형태로 만들어준다. 실제로는 객체 타입이지만, key의 이름을 자동으로 index로 붙여주기 때문에 유사배열이라 하는 것.

function paramToArguments(){
	return arguments;
}
let argumentsObj = paramToArguments('a', 'b', 'c');
console.log(argumentsObj); // { 0: 'a', 1: 'b', 2: 'c' }
}

조각모음

  • 함수의 전달인자도 변수에 자료를 할당한다. 함수를 호출하며 넘긴 전달인자는 호출을 할 때마다 함수의 지역변수로 새롭게 선언된다.
  • 매개변수에 객체 분해 할당을 사용할 수 있으며 객체 내의 값도 매개변수로 활용 할 수 있다.
    const student = {
      name: "최초보",
      major: "물리학과",
      lesson: "양자역학",
      grade: "B+"
    };
    
    function getSummary({ name, lesson: course, grade }) {
      return `${name}님은 ${grade}의 성적으로 ${course}을 수강했습니다`;
    }
    
    console.log(getSummary(student)); // "최초보님은 B+의 성적으로 양자역학을 수강했습니다"


Uploaded by N2T