본문 바로가기

공부기록용

[ javascript ] 순서도 정리 및 복습, 옵셔널 체이닝(?.)

***어제 공부에서 부족했던 부분 정리 및 기록

 

- 분기점을 합치는 작업 → 코드 간략화 코드를 최적화하는 과정의 이해가 부족해서 다시 정리 

 

-------------------------------------------------------------------------------------------------------------------

(입력) 버튼 클릭(이벤트 발생) → 제시어가 존재하는가? ---아니오→ 입력한 값이 제시어가 된다

                                                                           └ 예 → 입력한 값이 올바른가? --예 ┘

                                                                                            └아니오 →입력한 값이 올바르지 않다고 알림한다→끝

 

 

-------------------------------------------------------------------------------------------------------------------

                                                                                                                           ┌ false → 입력한 값이 올바르지 않다고 알림한다 → 끝

버튼 클릭 → 제시어가 존재하는가? -----true 입력값이 올바른가? -----true 입력값이 제시어가 된다

                                        └---false ------------------------------------------------------------------ ┘

                

제시어가 존재하는가? 에서 존재하지 않다면 바로 입력값이 제시어가 된다의 절차로 진행되어야 함

제시어가 존재하는가? 에서 존재하지 않는다고 하면 false 이니

존재하지 않음을 true로 만들어야 함 그렇다면 존재하지 않는가? 로 바꾼다면 제시어가 존재하지 않을 때 true가 되고,

||(or) 연산기호로 true면 우항의 연산을 진행하지 않고 바로 입력한 값이 제시어가 된다의 절차로 넘어가게됨

만약 제시어가 존재하지 않는가? 에서 false가 나오면 ||(or)연산기호에 의해 우항을 연산한다.

그래서 입력값이 올바른가의 연산 결과를 통해 다음 절차가 달라진다. 아래와 같이 이렇게 작성할 수 있다.

 

if(제시어가 존재하지 않는가?(제시어가 없는가?) ||  입력 값이 올바른가?) {

 입력한 값이 저장된 변수를 제시어를 담는 변수에 대입한다.

 html태그의 요소의 내용물을 담는 공간을 얻에 제시어를 담고 있는 변수를 대입한다.

 

/*

부수적으로 작성해야할 사항---------------------------------------------

html문서의 제시어 자리에 사용자가 입력한 값이 제시어가 된다면

- 후에 입력창에 작성했던 값을 비워주고, 커서를 입력창에 두기

- ( 다음 참가자에게 차례를 넘겨주기 위한 ) 다음 참가자의 순번을 정할 것

*/

 

 사용자로부터 입력 값을 받는 입력 창의 값에 빈 문자열을 대입하기

 입력 창에 커서두기

 

 현재 순번을 확인한 뒤 현재 순번에 +1을 더한 값이 총 참가자의 수보다 많다면

 다음 참가자의 순번은 1을 대입한다.

 현재 순번에 +1을 연산한 값이 총 참가자의 수보다 적다면

 다음 참가자의 순번은 현재 순번에 +1을 연산한 값을 대입한다.

 

}

 

- 입력 값이 올바른가? 의 코드를 작성하기

기존 제시어의 마지막 글자를 추출하고, 입력 값의 첫 번째 글자를 추출한 후 서로 비교한다.

일치한다면 true를 일치하지 않는다면 false를 반환하는 식을 작성한다면 아래와 같다.

우선 기존 제시어가 담긴 변수 word에서 마지막 글자를 추출한다면 word[word.length-1]

입력한 값이 담긴 변수 newWord에서 첫 글자를 추출한다면 newWord[0]

일치여부는 ===(엄격 일치 연산자, strict equal operator) 연산자로 비교한다.

 

- 다음 참가자의 순번 결정에 대한 코드를 작성할 때 기존에는 if~else문으로 작성했었다.

html---------------------------------------------------------------------------------------------------

 

<div> <span id="order"> 1</span>번째 참가자</div>

 

 

 

<script>-----------------------------------------------------------------------------------------------

- html문서에 있는 현재 참가자의 순번의 값을 가진 요소를 얻어서

const $order = document.querySelector('#order');

 

- 요소가 가진 값을 숫자 타입으로 변환한 뒤 새로운 변수에 대입한다.

const order = Number($order.textContent);

 

- 현재 순번에 +1을 연산한 값이 총 참가자 수보다 많다면

다음 참가자의 순번에는 1을 대입하고

아니라면 현재 순번에 +1을 연산한 값을 대입한다.

if(order+1>number) { // number에는 참가자의 총 수가 대입되어 있다.

 $order.textContent = 1;

} else {

 $order.textContent = order+1;

}

 

근데 위의 if~else문을 삼항 연산자로 작성할 수 있다.

5줄을 단 2줄로 작성할 수 있다(코드의 간결화)

 

const order = Number($order.textContent);
$order.textContent = order + 1 > number ? 1 : order + 1;

 

-------------------------------------------------------------------------------------------------------------------

 

***optional chaning(옵셔널 체이닝)은 다음과 같은 기호를 사용한다: ?.

1. 객체의 속성(Object's property)에 접근하거나

2. 함수를 호출한다.

?. 기호를 사용해서 접근한 객체 또는 호출된 함수가 undefined 또는 null 이라면

표현식은(the expression) 단축 평가하고(short circuits) error를 발생하는 대신에 undefined로 평가한다.

***short-circuiting은 진행을 중단하고 바로 결과를 반환한다는 의미다. 예를 들어 &&(AND)나 ||(OR) 연산자를 사용할 때,

조건식이 특정 조건식을 만족하면 뒤의 조건을 아예 평가하지 않고 결과를 반환한다.

 

const user = { name: 'sungju', age: 10, };

console.log(user.address?.city);

→ user객체는 address 속성을 가지고 있지 않으므로 undefined를 반환한다.

user.address가 undefined를 반환함으로 ?.(옵셔널 체이닝)은 단축 평가(short-circuiting)를 하고,

address에서 city의 값으로는 아예 접근하지도 않고 undefined를 반환하는 것으로 마친다.

중요한 점은 에러를 발생시키지 않고 undefined를 반환한다는 것

 

옵셔널 체이닝(?.)이 등장한 배경은 객체가 지니지 않은 속성에 접근할 때 에러가 발생하는데

→ 더 구체적으로 객체가 어떤 속성을 지니고 있지 않을 때 해당 속성을 출력하면 그 속성의 값은 undefined로 출력되는데

이렇게 undefined로 출력되는 속성에 접근해서 그 속성이 지니는 값을 또 접근하려고 하면 에러가 발생한다.

예를 들어

const user = { name: 'sungju', age: 10, };

console.log(user.address); // 이거는 undefined가 반환되는데

console.log(user.address.city); // 이거는 에러가 발생한다.

 

또 자바스크립트를 사용해 페이지(html문서)에 존재하지 않는 요소에 접근해 요소의 정보를 가져오려고 하면 문제가 발생한다.

존재하지 않는 요소는 null을 반환하고, null인데 뭔가에 또 접근하려고 하니 에러를 발생시키는 것

 

옵셔널 체이닝?. 은  ?. '앞'의 평가 대상이 undefined나 null이면 평가를 멈추고(short-circuiting)

undefined를 반환한다. 옵셔널 체이닝이 없었을 때는 &&연산자를 사용해서 코드를 작성했었다.

예를 들면

 

let user = {};

console.log(user.address); // undefined가 반환됨

console.log(user.address.city); // 에러가 발생함. 에러가 발생하지 않기 위해서 아래와 같이 작성했다.

console.log(user && user.address && user.address.city); // undefined가 반환됨

 

// 옵셔널 체이닝이 나온 이후로 아래와 같이 작성할 수 있다.

console.log(user?.address?.city); // undefined가 반환됨

→ user가 존재한다면 user가 지니는 address의 속성에 접근하고, user.address가 존재한다면 .city에 접근한다.

→ 단, user는 변수는 반드시 존재해야함(변수는 선언되어 있어야 한다) 존재하지 않으면 에러를 발생시킨다.

 

```

 

(*단, user라는 변수는 선언되어 있음)

user라는 변수가 있니? ---true→user의 값이 반환됨

└false→에러가 난다. 옵셔널 체이닝은 선언이 완료된 변수를 대상으로만 동작한다.

user에 속성 address가 있니? ---true→ user.address의 값이 반환됨

└false→undefined가 반환됨

---user.address가 city의 속성을 갖고 있니? ---true→user.address.city의 값이 반환됨

└false→undefined가 반환됨

 

```

 

존재여부가 확실치 않은 함수를 옵셔널 체이닝으로 호출할 수 있다.

?.은 함수나 대괄호와 함께 동작하는 특별한 문법 구조체다.

→ obj?method(): obj가 존재하면 method() 메서드를 호출하고

obj가 존재하지 않거나(선언은 되었으나 값이 할당되지 않았을 때)

obj가 존재하지만 method() 함수가 선언되어 있지 않으면 undefined를 반환한다. 

?.은 delete와 조합해서 사용할 수도 있다.

 

옵셔널 체이닝 문법은 ?. 왼쪽 평가 대상이 undefined나 null인지 확인하고,

null이나 undefined가 아니라면 우항의 평가를 계속 진행한다.

- .?를 계속 연결해서 체인을 만들면 중첩 프로퍼티(속성)들에 안전하게 접근할 수 있다.

 

참고 --------------------------------------------------------------------------------------------------------

옵셔널 체이닝 관련 참고 페이지: https://ko.javascript.info/optional-chaining