모던 javascript 튜토리얼 30

옵셔널 체이닝 '?.'

옵셔널 체이닝(optional chaining) ?.을 사용하면 프로퍼티가 없는 중첩 객체를 에러 없이 안전하게 접근할 수 있습니다. 옵셔널 체이닝이 필요한 이유 사용자가 여러 명 있는데 그중 몇 명은 주소 정보를 가지고 있지 않다고 가정해봅시다. 이럴 때 user.address.street를 사용해 주소 정보에 접근하면 에러가 발생할 수 있습니다. let user = {}; // 주소 정보가 없는 사용자 alert(user.address.street); // TypeError: Cannot read property 'street' of undefined 또 다른 사례론 브라우저에서 동작하는 코드를 개발할 때 발생할 수 있는 문제가 있습니다. 자바스크립트를 사용해 페이지에 존재하지 않는 요소에 접근해 요..

new 연산자와 생성자 함수

객체 리터럴 {...} 을 사용하면 객체를 쉽게 만들 수 있습니다. 그런데 개발을 하다 보면 유사한 객체를 여러 개 만들어야 할 때가 생기곤 합니다. 복수의 사용자, 메뉴 내 다양한 아이템을 객체로 표현하려고 하는 경우가 그렇죠. 'new' 연산자와 생성자 함수를 사용하면 유사한 객체 여러 개를 쉽게 만들 수 있습니다. 생성자 함수 함수 이름의 첫 글자는 대문자로 시작합니다. 반드시 'new' 연산자를 붙여 실행합니다. function User(name) { this.name = name; this.isAdmin = false; } let user = new User("보라"); alert(user.name); // 보라 alert(user.isAdmin); // false new User(...)를 써..

메서드와 this

객체는 사용자(user), 주문(order) 등과 같이 실제 존재하는 개체(entity)를 표현하고자 할 때 생성됩니다. let user = { name: "John", age: 30 }; 자바스크립트에선 객체의 프로퍼티에 함수를 할당해 객체에게 행동할 수 있는 능력을 부여해줍니다. 메서드 만들기 객체 user에게 인사할 수 있는 능력을 부여해 줍시다. let user = { name: "John", age: 30 }; user.sayHi = function() { alert("안녕하세요!"); }; user.sayHi(); // 안녕하세요! 함수 표현식으로 함수를 만들고, 객체 프로퍼티 user.sayHi에 함수를 할당해 주었습니다. 이제 객체에 할당된 함수를 호출하면 user가 인사를 해줍니다. 이렇..

가비지 컬렉션

자바스크립트는 눈에 보이지 않는 곳에서 메모리 관리를 수행합니다. 원시값, 객체, 함수 등 우리가 만드는 모든 것은 메모리를 차지합니다. 그렇다면 더는 쓸모 없어지게 된 것들은 어떻게 처리될까요? 지금부턴 자바스크립트 엔진이 어떻게 필요 없는 것을 찾아내 삭제하는지 알아보겠습니다. 가비지 컬렉션 기준 아래 소개해 드릴 값들은 그 태생부터 도달 가능하기 때문에, 명백한 이유 없이는 삭제되지 않습니다. 예시: 현재 함수의 지역 변수와 매개변수 중첩 함수의 체인에 있는 함수에서 사용되는 변수와 매개변수 전역 변수 기타 등등 이런 값은 *루트(root)*라고 부릅니다. 루트가 참조하는 값이나 체이닝으로 루트에서 참조할 수 있는 값은 도달 가능한 값이 됩니다. 전역 변수에 객체가 저장되어있다고 가정해 봅시다. 이..

참조에 의한 객체 복사

객체와 원시 타입의 근본적인 차이 중 하나는 객체는 ‘참조에 의해(by reference)’ 저장되고 복사된다는 것입니다. let message = "Hello!"; let phrase = message; 그런데 객체의 동작방식은 이와 다릅니다. 변수엔 객체가 그대로 저장되는 것이 아니라, 객체가 저장되어있는 '메모리 주소’인 객체에 대한 '참조 값’이 저장됩니다. 그림을 통해 변수 user에 객체를 할당할 때 무슨 일이 일어나는지 알아봅시다. let user = { name: "John" }; 객체는 메모리 내 어딘가에 저장되고, 변수 user엔 객체를 '참조’할 수 있는 값이 저장됩니다. 따라서 객체가 할당된 변수를 복사할 땐 객체의 참조 값이 복사되고 객체는 복사되지 않습니다. let user = ..

객체

자료형챕터에서 배웠듯이 자바스크립트엔 여덟 가지 자료형이 있습니다. 이 중 일곱 개는 오직 하나의 데이터(문자열, 숫자 등)만 담을 수 있어 '원시형(primitive type)'이라 부릅니다. 그런데 객체형은 원시형과 달리 다양한 데이터를 담을 수 있습니다. 키로 구분된 데이터 집합이나 복잡한 개체(entity)를 저장할 수 있죠. 객체는 자바스크립트 거의 모든 면에 녹아있는 개념이므로 자바스크립트를 잘 다루려면 객체를 잘 이해하고 있어야 합니다. 서랍장을 상상하면 객체를 이해하기 쉽습니다. 서랍장 안 파일은 프로퍼티, 파일 각각에 붙어있는 이름표는 객체의 키라고 생각하시면 됩니다. 복잡한 서랍장 안에서 이름표를 보고 원하는 파일을 쉽게 찾을 수 있듯이, 객체에선 키를 이용해 프로퍼티를 쉽게 찾을 수 ..

폴리필

자바스크립트는 끊임없이 진화하는 언어입니다. 새로운 제안(proposal)이 정기적으로 등록, 분석되고, 가치가 있다고 판단되는 제안은 https://tc39.github.io/ecma262/에 추가됩니다. 그리고 궁극적으로 명세서(specification)에 등록됩니다. 엔진이 표준 전체를 지원하지 않고 일부만 지원하는 건 흔한 일이죠. 엔진별로 어떤 기능을 지원하고 있는지는 https://kangax.github.io/compat-table/es6/에서 확인할 수 있습니다. 표가 상당히 큰데, 각 기능에 대해선 차근차근 배울 예정이니 너무 겁먹지 않으셔도 됩니다. 바벨 바벨(Babel)은 트랜스파일러(transpiler)로, 모던 자바스크립트 코드를 구 표준을 준수하는 코드로 바꿔줍니다. 트랜스파일러..

테스트 자동화와 Mocha

테스트 자동화는 앞으로 풀어야 할 과제에서뿐만 아니라 현업에서도 광범위하게 쓰입니다. 테스트는 왜 해야 하는가? 개발 중엔 콘솔 창 등을 이용해 실제 실행 결과가 기대했던 결과와 같은지 계속 비교하면서 원하는 기능이 잘 구현되고 있는지 확인할 겁니다. 실제 실행 결과가 기대했던 결과와 다를 땐, 코드를 수정하고 다시 실행해 그 결과를 기대했던 결과와 다시 비교해 볼 겁니다. 원하는 기능을 완성할 때까지 이 과정을 계속 반복하겠죠. 코드를 수동으로 ‘재실행’ 하면서 테스트를 하면 무언가를 놓치기 쉽습니다. Behavior Driven Development BDD는 테스트(test), 문서(documentation), 예시(example)를 한데 모아놓은 개념입니다. 개발 순서 실제 개발에 착수하면 아래와 ..

닌자 코드

https://ko.javascript.info/ninja-code 닌자 코드 ko.javascript.info 이 글은 반어법입니다. 닌자라 불리던 전설 속 개발자들은 유지보수 담당 개발자를 혹독하게 훈련하고자 (아래에서 소개해 드릴) 다양한 편법을 사용하곤 했습니다. 구루 급의 코드 리뷰 전문가들은 테스트 코드에서 이런 편법을 발견하면 박수갈채를 보내곤 했죠. 어떨 때는 초보 개발자가 닌자보다 더 적극적으로 나서서 이런 편법을 사용하곤 합니다. 닌자가 사용하던 편법을 잘 살펴보시고, 자신은 닌자인지, 코드 리뷰어인지, 초보 개발자인지 판단해 보시기 바랍니다. 코드 짧게 쓰기 가능한 한 코드를 짧게 써서, 당신이 얼마나 똑똑한 사람인지 보여주십시오. 지엽적인 문법 지식 등을 총동원하면 코드 양을 획기적..

주석

코드 구조에서 알아본 바와 같이 한 줄짜리 주석은 //로, 여러 줄의 주석은 /* ... */로 시작합니다. 주석(comment)은 어떻게 코드가 동작하는지, 왜 코드가 동작하는지를 설명하는 데 쓰입니다. 주석을 작성하는 게 쉬워 보일 수 있는데, 초보 개발자들은 종종 잘못된 방법으로 주석을 작성하는 실수를 범합니다. 좋지 않은 주석 // 이 코드는 (...)과 (...)을 수행합니다 // A라는 개발자가 이 기능에 대해 알고 있으며... very; complex; code; 이와 관련된 좋은 규칙도 있습니다. “코드가 불분명해서 주석 작성이 불가피하다면 코드를 다시 작성해야 하는 지경에 이른 걸 수 있습니다.” 리팩토링 팁: 함수 분리하기 function showPrimes(n) { for (let i..