자바스크립트 어려운 개념 및 문법 정리

young-gue Park·2023년 1월 25일
0

JavaScript

목록 보기
11/20
post-thumbnail

⚡ 모르겠으면... 알 때까지 봐라


📌 스코프와 클로저

🔷 스코프

  • 변수가 어느 범위까지 참조되는 지를 뜻한다. (전역, 지역)

🔷 클로저

  • 함수가 선언된 환경의 스코프를 기억하여 함수가 스코프 밖에서 실행될 때에도 기억한 스코프에 접근할 수 있게 만드는 문법

❗ 기초 개념 학습에서 한번 짚고 넘어갔던 개념이다.
바로 여기에서

MDN에서는 클로저를 함수와 그 함수가 선언 됐을 때의 렉시컬 환경과의 조합이라고 표현했다.
이 알 수 없는 미묘한 뜻 해석에 많은 사람들이 벽을 느꼈을 듯 하다. 나도 그랬다.
진즉에 예시 코드로 알아보면 참 좋았을 것을.

🖥 예시 코드

let GlobalNum;
GlobalNum = 7;

function addNum(num) {
    console.log(GlobalNum + num);
}

addNum(10);

렉시컬 환경을 먼저 살펴보자면 addNum 함수 내부 하나, 전역 환경 하나 이렇게 둘이다.
addNum 렉시컬 환경에서는 GlobalNum이라는 변수가 존재하지 않는다.
그럼에도 이 함수는 정상 작동한다.

🖨 출력

왜냐하면 addNum이 본인의 환경에서 찾지 못한 GlobalNum을 찾기 위해 전역 렉시컬 환경을 참조하였기 때문이다.
이것이 클로저의 개념.

아... 사실 우리는 이미 클로저를 우리도 모르게 사용하고 있었던 것이었다...

그렇다면 이 클로저를 어떻게 더 응용하는 것일까?
자바로 프로그래밍 공부를 시작했던 나로서 클로저로 private 대신 어떻게 은닉화를 한다는 것인지 궁금하던 참이었다.

🖥 예시 코드

function myName(name){
    return {
        getName : function (){
            return name;
        },
        setName : function(_name){
            name = _name
        }
    }
}

gue = myName('박영규');
hoon = myName('박영훈');
 
console.log(gue.getName());
console.log(hoon.getName());
 
gue.setName('김영규');
 
console.log(gue.getName());
console.log(hoon.getName());

🖨 출력

이전 코드에서 전역 환경을 참조하였다면 이 코드에서는 내부 함수가 외부 함수를 참조하였다.
myName 지역 변수인 name에 접근하려면 return되는 객체 내부의 메서드를 활용해야만 한다.
마치 자바에서 private을 이용해 선언한 변수에 get메서드와 set메서드를 활용하여 접근하는 것과 같다.
이런 식으로 자바스크립트에서는 클로저를 정보 은닉에 이용한다.


📌 비구조화(구조 분해)할당

  • 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 자바스크립트 표현식
  • ES6부터 제공하기 시작했다.

❗ [...]{...} 문법 (스프레드 오퍼레이터)에 대해 설명하며 언급했었다.
여기서 설명했었다.

배열이나 객체 안의 값을 하나하나 꺼내서 직접 지정하는 것이 번거로워 생긴 문법이다.
예를 들어 우리가 롤 시즌 별 티어를 기록하였다고 가정하고 코드를 짠다.

🖥 예시 코드

const tierList = ['Iron', 'Bronze', 'Silver', 'Gold', 'Platinum', 'Diamond', 'Master', 'Grandmaster', 'Challenger']

const season3 = tierList[8];
const season6 = tierList[6];
const season10 = tierList[4];

console.log(season3);
console.log(season6);
console.log(season10);

🖨 출력

하나하나 새로 변수를 선언함과 동시에 배열에서 값을 꺼내어 지정하는 방식은 번거롭다.

그래서 이 코드를 이렇게 간결하게 바꿀 수 있다.

const [season3, season6, season10] = ['Challenger', 'Master',  'Platinum']
console.log(season3);
console.log(season6);
console.log(season10);

이렇게 하면 같은 결과를 내지만 코드의 수도 훨씬 줄어들고 보기에도 좋다.
이것이 비구조화 할당의 기본 개념이다.
이러한 개념은 다양한 트릭이 가능하게 한다.

// 변수 swap하기
let a = 5, b = 10;
[a, b] = [b, a];
console.log(a, b); // 10 5

비구조화 할당 문법 중에는 지난번에 보았던 스프레드 오퍼레이터([...], {...})도 있다.
이 녀석은 기존 배열이나 객체의 값 복제를 간단하게 한다.

🖥 예시 코드

const tierList = ['Iron', 'Bronze', 'Silver', 'Gold', 'Platinum', 'Diamond', 'Master', 'Grandmaster', 'Challenger']
let newTier = [...tierList]
console.log(newTier);

// 당연히 객체도 된다
let tierObj = {
    season1: 'Bronze',
    season2: 'Silver'
};
let newTierObj = {...tierObj};
console.log(newTierObj);

🖨 출력

값 분리도 할 수 있고,

🖥 예시 코드

const tierList2 = ['Grandmaster', 'Bronze', 'Silver', 'Gold', 'Platinum', 'Diamond', 'Master', 'Challenger']
const [season4, ...otherSeasonList] = tierList2;

console.log(season4);
console.log(otherSeasonList);

🖨 출력

Set()을 이용해 같은 요소 제거도 할 수 있다.

const names = ['Lee', 'Kim', 'Park', 'Lee', 'Kim'];
const uniqueNamesWithArrayFrom = Array.from(new Set(names));
const uniqueNamesWithSpread = [...new Set(names)];

이 외에도 배열과 객체에 적용 가능한 비구조화 할당 문법은 다양하나 이곳에서 모두 언급하기에는 양이 많으니 넘어간다.


📌 논리 연산자 응용하기

🔷 자바스크립트에서는 논리 연산자를 조건문 이외에도 다양하게 이용할 수 있다.
🖥 '&&', '||' 활용 예시 코드

/// ||
// 기본값을 넣어주고 싶을 때 사용할 수 있다.
// participantName이 0, undefined, 빈 문자열, null일 경우 'Guest'로 할당
const name = participantName || 'Guest';

/// &&
// flag가 true일 경우에만 실행
flag && func();

// 객체 병합에도 이용할 수 있다.
const makeCompany = (showAddress) => {
  return {
    name: 'Cobalt. Inc.',
    ...showAddress && { address: 'Seoul' }
  }
};
console.log(makeCompany(false));
// { name: 'Cobalt. Inc.' }
console.log(makeCompany(true));
// { name: 'Cobalt. Inc.', address: 'Seoul' }

🖥 '!!' 활용 예시 코드

// !! 연산자를 이용하여 0, null, 빈 문자열, undefined, NaN을 false로 그 외에는 true로 변경할 수 있다.
function check(variable) {
  if (!!variable) {
    console.log(variable);
  } else {
    console.log('잘못된 값');
  }
}
check(null); // 잘못된 값
check(3.14); // 3.14
check(undefined); // 잘못된 값
check(0); // 잘못된 값
check('Good'); // Good
check(''); // 잘못된 값
check(NaN); // 잘못된 값
check(5); // 5

자바를 공부하면서 먼저 접했던 연산자들이지만 한번도 자바를 쓰면서 이런 식으로 활용해본 적은 없었다.
자바스크립트를 배우면서 마주하고 엉뚱하게 느껴졌던 논리 연산자들이 이제야 이해가 간다...


지금까지 공부하던중 헷갈리지만 중요하다고 생각했던 부분들을 짚어보았다.
이제 마저 진도를 나가도록 한다.

profile
Hodie mihi, Cras tibi

0개의 댓글