간단한 코드를 작성하던 중, 변수 x와 y를 선언 시 동일한 값을 할당할 것이기 때문에 한 줄에 짧게 작성할 수 있는지 궁금해졌다.
1) let p, y = 0 ❌
function solution(s){
const str = s.toLowerCase();
let p, y = 0;
for(let i of str) {
if(i === 'p') p++;
if(i === 'y') y++;
}
return p === y ? true : false;
}
위의 코드를 실행했을 때 p값이 제대로 담기지 않아 for문 안에 console.log을 넣어 확인해 보았다.
function solution(s){
const str = s.toLowerCase();
let p, y = 0;
for(let i of str) {
console.log(i);
if(i === 'p') p++;
if(i === 'y') y++;
console.log(p, y)
}
return p === y ? true : false;
}
p가 NaN(Not a Number)으로 찍히고 있었다. p의 값을 제대로 찾지 못하고 있다.
2) let p = let y = 0; ❌
function solution(s){
const str = s.toLowerCase();
let p = let y = 0;
for(let i of str) {
if(i === 'p') p++;
if(i === 'y') y++;
}
return p === y ? true : false;
}
Unexpected identifier 오류가 발생한다. 해당 오류는 대부분 오탈자에서 발생한다고 한다. let y 부분이 유효하지 않다는 것.
3) let p = y = 0; 🔺
function solution(s){
const str = s.toLowerCase();
let p = y = 0;
for(let i of str) {
if(i === 'p') p++;
if(i === 'y') y++;
}
return p === y ? true : false;
}
실행이 되긴 한다. 하지만 변수 y도 let 키워드가 제대로 적용된 건지가 궁금해졌다. 확인해 보기 위해 let을 const로 바꿔서 찍어보았다.
let 키워드를 const로 바꿔서 확인해보기
function solution(s){
const str = s.toLowerCase();
const p = y = 0;
for(let i of str) {
console.log(i);
if(i === 'p') p++;
if(i === 'y') y++;
console.log(p, y)
}
return p === y ? true : false;
}
먼저 실행되는 문인 p++에서 p가 const이기 때문에 값을 바꿀 수 없다는 오류가 발생했다. 그렇다면 해당 문을 주석처리하고 y만 실행되도록 했을 때는? y도 const 처리가 되고 있는 걸까?
y도 const가 적용되고 있는지 확인해 보기
function solution(s){
const str = s.toLowerCase();
const p = y = 0;
for(let i of str) {
console.log(i);
// if(i === 'p') p++;
if(i === 'y') y++;
console.log(p, y)
}
return p === y ? true : false;
}
y에는 const 적용이 되지 않고 값이 잘 바뀌고 있다. 따라서 const p = y = 0;을 할 경우 대입 연산자는 오른쪽의 값을 왼쪽에 대입하므로 0의 값이 대입은 되나, y에는 const 키워드가 적용되지 않는다는 것이다.
🔬 let p = y = 0;에서 y가 전역 변수인지 확인해 보기
키워드 없이 y를 선언한다면 당연히 전역 변수 처리가 될 텐데, let p = y = 0;의 경우에도 y가 전역 처리가 되는지 궁금해졌다. 전역 변수처리가 되는지 확인해 보기 위해 let p = y = 0;을 함수 안에 넣어보았다. (함수 내에서 let으로 변수를 선언할 경우 해당 함수 안에서만 유효하다.)
* 일반적인 경우
function solution(s){
let p = 0;
if(p === 0) { let y = 1; }
console.log(y);
}
ReferenceError: y is not defined 에러가 출력된다. y가 정의되지 않았다는 뜻이다. 왜냐면 y는 let 키워드로 선언되어 해당 함수 안에서만 유효하기 때문이다!
* let p = y = 0;의 경우
function solution(s){
let z = 0;
if(z === 0) { let p = y = 1; }
console.log(y);
}
y의 값인 1이 콘솔에 찍히고 있다. console.log(y)가 아니라 console.log(p, y)를 하면 p는 위의 not defined에러가 뜨게 된다. 따라서 p는 let 키워드 적용이 되고 있고, y는 전역 처리가 된다는 것을 확인할 수 있었다. 특별한 의미나 의도 없이 변수를 전역처리하면 안 된다고 생각하기 때문에 (그것을 방지하기 위해 ES6에서 나온 기존의 var의 대안으로 나온 키워드가 let, const이기도 하다.) let p = y = 0;은 사용하지 않고 다른 방법을 더 찾아보았다.
4) let p = 0, y = 0; ⭕
function solution(s){
const str = s.toLowerCase();
let p = 0, y = 0;
for(let i of str) {
if(i === 'p') p++;
if(i === 'y') y++;
}
return p === y ? true : false;
}
실행이 잘 된다! 그렇다면 y가 let 키워드를 잘 적용받고 있는지 다시 확인해 보자.
function solution(s){
let z = 0;
if(z === 0) { let p = 1, y = 1; }
console.log(y);
}
함수 내부에 y를 정의하고 함수 밖에서 y를 콘솔로 찍어보았을 때, y가 정의되지 않았다는 y is not defined 오류가 뜬다! 따라서 let 키워드가 적용되었다.
위와 같이 한 줄에 변수를 정의해 코드가 짧아 보이는 것도 좋지만, 권장하는 방법은 아니라고 한다. 가독성을 위해서는 한 줄에 하나의 변수를 작성하는 게 좋다. 코드는 길어 보이지만 가독성은 훨씬 좋기 때문이다.
let user = 'John'
, age = 25
, message = 'Hello';
✅ 프로그래머스 문제를 풀고 다른 사람들이 푼 답안을 보다 보면 최대한 짧고 간결하게 작성한 코드들을 매번 확인할 수 있다. 이전에 프로그래머스에서 본 댓글처럼 '보기 좋은' 코드보다 '정말 효율성 있고 좋은 코드'를 작성하는 게 더 중요하겠지만 그래도 이 부분은 어떻게 간결하게 처리해 볼 수 없을까? 한 번 더 생각해 보게 된다.
변수를 한 줄에 작성해보려 했던 것도 그러한 이유인데, 내 의도와 다르게 오류를 뱉어내고 이렇게 저렇게 찾아보고 시도해 보면서 최종적으로 내 의도에 맞는 문을 찾아낼 수 있어서 재밌었다.
[참고 자료]
https://school.programmers.co.kr/learn/courses/30/lessons/12916
https://ko.javascript.info/variables
'Front-End > JavaScript' 카테고리의 다른 글
[JavaScript] 브라우저 렌더링 과정(원리) (9) | 2023.04.14 |
---|---|
[JavaScript] 자바스크립트로 숫자야구 프로그램 만들기 (0) | 2023.04.07 |
[JavaScript] Uncaught ReferenceError: Cannot access 'X' before initialization (0) | 2023.04.03 |
[노마드코더 / 바닐라JS] momentum 클론 코딩(4)_To do and Weather (0) | 2023.03.25 |
[freeCodeCamp / 바닐라JS] 초보자를 위한 바닐라JS 프로젝트(1)_Color Flipper (1) | 2023.03.25 |