[비개발자의 앱 개발 수난기 #6] 자바스크립트 기초 문법 2

자바스크립트 기초 문법 공부한 내용을 복습하기 위해 작성한 것으로, 벨로퍼트와 함께하는 모던 자바스크립트 강의 내용을 발췌했습니다.

자바스크립트 기초 문법

자바스크립트 기초 문법: 1. 삼항 연산자

조건에 따라 text 값이 달라야 하는 상황이 있다고 가정해 봅시다.

const array = [];
let text = '';
if (array.length === 0){
    text = '배열이 비어있습니다.';
} else {
    text = '배열이 비어있지 않습니다.';
}

console.log(text);
// 배열이 비어있습니다.

삼항 연산자를 사용하면 위 코드를 아래와 같이 작성할 수도 있습니다.

const array = [];
let text = array.length === 0 ? '배열이 비어있습니다.' : '배열이 비어있지 않습니다.';

console.log(text);
// 배열이 비어있습니다.

삼항 연산자의 사용법은 아래와 같습니다.

조건 ? true일 때 : false일 때;

라인이 너무 길어진다면 아래와 같이 작성하기도 합니다.

const array = [];
let text = array.length === 0 
    ? '배열이 비어있습니다.' 
    : '배열이 비어있지 않습니다.';

console.log(text);
// 배열이 비어있습니다.




자바스크립트 기초 문법: 2. Truthy and Falsy

아래와 같이 코드를 작성해 봅시다.

console.log(!null);
// true
console.log(!undefined);
// true

값이 true가 되는 것을 확인할 수 있습니다. undefined 와 null 은 Falsy한 입니다. Falsy 한 값 앞에 느낌표를 붙여주면 true 로 전환됩니다.

Falsy한 값이란 거짓 같은  값을 뜻하며, 값은 불리언 문맥에서 false로 평가되는 값입니다. Falsy한 값은 아래와 같이 몇 개 더 있습니다.

console.log(!undefined);
// true
console.log(!null);
// true
console.log(!0);
// true
console.log(!'');
// true
console.log(!NaN); // 숫자가 아님
// true

그 외의 값은 모두 Truthy한 값입니다. Truthy한 값이란 불리언을 기대하는 문맥에서 true로 평가되는 값입니다. 

console.log(!3);
// false
console.log(!'hello');
// false
console.log(!['array?']);
// false
console.log(![]);
// false
console.log(!{ value: 1 });
// false




자바스크립트 기초 문법: 3. 단축 평가 (short-circuit evaluation) 논리 계산법

자바스크립트의 논리 연산(AND, OR 등등..)은 왼쪽에서 오른쪽으로 이뤄집니다. 이때 앞의 비교에서 명확한 결과가 예측되어 뒤에 나오는 비교를 더 이상 할 필요가 없을 때 비교를 중지하고 답을 내는 것입니다.

이전에 연산자를 배울 때, 아래와 같은 사항을 공부했습니다.

true && true // true
true && false // false
true || false // true
false || true // true

그렇다면 아래와 같은 상황에서 값은 어떻게 출력될까요?

console.log( 0 || 1 ); 
console.log( 0 && 1 ); 
console.log( 1 || 'hello' ); 
console.log( 1 && 'hello' ); 

답은 위에서 부터 차례대로 1, 0, 1, hello 입니다. 여기서 두 번째, 세 번째 연산에 대해 살펴 봅시다.

AND(&&) 연산에서 앞에 위치한 인수가 이미 Falsy 이기 때문에 뒤의 조건은 비교할 필요가 없으며, 따라서 앞에 위치한 인수가 출력됩니다.
OR(||) 연산에서 앞에 위치한 인수가 이미 Truthy 이기 때문에 뒤의 조건은 비교할 필요가 없으며, 따라서 앞에 위치한 인수가 출력됩니다.
이러한 속성을 잘 알아두면, 특정 값이 유효할 때에만 어떤 값을 조회하는 작업을 해야 할 때 유용합니다.




자바스크립트 기초 문법: 4. 함수의 기본 파라미터

함수의 매개변수는 undefined가 기본입니다. 그러나, 일부 상황에서는 다른 기본 값을 설정하는 것이 유용할 수 있습니다. 함수의 기본 파라미터를 설정하는 방법에 대해서 알아봅시다.

function multiply(a, b) {
  return a * b
}

multiply(5, 2)  // 10
multiply(5)     // NaN !

위 코드를 보면 파라미터에서 b 값을 받아오지 못할 경우, 5 * undefined 가 됩니다. 그래서 결과는 Not a Number 라는 의미로 NaN이 호출됩니다.

이를 방지하기 위해서 b의 기본값을 1로 설정할 수 있습니다.

function multiply(a, b = 1) {
  return a*b
}

multiply(5, 2)          // 10
multiply(5)             // 5
multiply(5, undefined)  // 5




자바스크립트 기초 문법: 5. 조건문 더 스마트하게 쓰기

특정 값이 여러 값 중 하나인지 확인해야 할 때

function isAnimal(text) {
  return (
    text === '고양이' || text === '개' || text === '거북이' || text === '너구리'
  );
}

console.log(isAnimal('개')); // true
console.log(isAnimal('노트북')); // false

위와 같이 작성할 수도 있겠지만, 배열을 만들고 배열의 includes 함수를 사용하면 코드를 보다 간결하게 작성 수 있습니다.

function isAnimal(text) {
  const animals = ['고양이', '개', '거북이', '너구리'];
  return animals.includes(name);
}

console.log(isAnimal('개')); // true
console.log(isAnimal('노트북')); // false

아래와 같이 화살표 함수로도 작성할 수도 있습니다.

const isAnimal = name => ['고양이', '개', '거북이', '너구리'].includes(name);

console.log(isAnimal('개')); // true
console.log(isAnimal('노트북')); // false


값에 따라 다른 결과물을 반환 해야 할 때

동물 이름을 받아오면 동물의 소리를 반환하는 함수를 만든다고 가정해 봅시다.

function getSound(animal) {
    if(animal === '개') return '멍멍!';
    if (animal === '고양이') return '야옹~';
    if (animal === '참새') return '짹짹';
    if (animal === '비둘기') return '구구 구 구';
    return '값이 없습니다.';
}
console.log(getSound('개')); // 멍멍!
console.log(getSound('비둘기')); // 구구 구 구

위 코드는 아래와 같이 좀 더 깔끔하게 작성할 수 있습니다.

function getSound(animal){
    const sounds = {
        개: '멍멍!',
        고양이: '야옹~',
        참새: '짹짹',
        비둘기: '구구 구 구'
    };
    return sounds[animal] || '값이 없습니다.';
}

console.log(getSound('개')); // 멍멍!
console.log(getSound('비둘기')); // 구구 구 구

값에 따라 실행해야 하는 코드 구문이 다를 때는 어떻게 해야 할까? 그럴 떄는 객체에 함수를 넣으면 됩니다.

function getSound(animal){ 
    const tasks = {
        개(){
            console.log('멍멍');
        },
        고양이(){
            console.log('야옹~');
        },
        비둘기(){
            console.log('구구 구 구');
        }
    };
    if(!tasks[animal]){
        console.log('값이 없습니다.');
        return;
    }
    tasks[animal]();
}

getSound('개'); // 멍멍!
getSound('비둘기'); // 구구 구 구



자바스크립트 기초 문법: 6. 비구조화 할당 (구조분해) 문법

비구조화 할당(destructuring assignment)은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 자바스크립트 표현식입니다.

const object = { a: 1, b: 2 };

const { a, b } = object;

console.log(a); // 1
console.log(b); // 2

위와 같이 비구조화 할당 문법을 사용하면 객체 안의 값을 꺼내 변수 혹은 상수로 바로 선언해 줄 수 있습니다. 또한 아래와 같이 함수의 파라미터에 비구조화 할당을 할 수도 있습니다.

const object = { a: 1, b: 2 };

function print({ a, b }) {
  console.log(a);
  console.log(b);
}

print(object); 
// 1
// 2


비구조화 할당 시 기본값 설정

b에 기본값을 주고 싶다면 아래와 같이 작성할 수 있습니다.

const object = { a: 1 };

function print({ a, b = 2 }) {
  console.log(a);
  console.log(b);
}

print(object);
// 1
// 2
const object = { a: 1 };

const { a, b = 2 } = object;

console.log(a); // 1
console.log(b); // 2

배열 비구조화 할당

비구조화 할당을 배열에서도 할 수 있습니다.

const array = [1, 2];
const [one, two] = array;

console.log(one); // 1
console.log(two); // 2

이 문법은 배열 안에 있는 원소를 다른 이름으로 새로 선언해주고 싶을 때 사용하면 매우 유용합니다.

객체 비구조화 할당과 마찬가지로, 기본값 지정이 가능합니다.

const array = [1];
const [one, two = 2] = array;

console.log(one); // 1
console.log(two); // 2


깊은 값 비구조화 할당

객체의 깊숙한 곳에 들어있는 값을 꺼내는 방법을 알아보자. 예를 들어 다음과 같은 객체가 있다고 가정해 봅시다.

const deepObject = {
  state: {
    information: {
      name: 'velopert',
      languages: ['korean', 'english', 'chinese']
    }
  },
  value: 5
};

name, languages, value 값들을 밖으로 꺼내려면 어떻게 해야할까요? 이럴 땐 두 가지 해결 방법이 있는데, 그 중 첫 번째는 비구조화 할당 문법을 두 번 사용하는 것입니다.

const deepObject = {
  state: {
    information: {
      name: 'velopert',
      languages: ['korean', 'english', 'chinese']
    }
  },
  value: 5
};

const { name, languages } = deepObject.state.information;
const { value } = deepObject;

const extracted = {
  name,
  languages,
  value
};

console.log(extracted); // {name: "velopert", languages: Array[3], value: 5}

두 번째 방법으로 한 번에 모두 추출하는 방법을 사용하는 것입니다. 이렇게 하면 깊숙이 안에 들어있는 값도 객체에서 바로 추출 할 수 있습니다.

const deepObject = {
  state: {
    information: {
      name: 'velopert',
      languages: ['korean', 'english', 'chinese']
    }
  },
  value: 5
};

const {
  state: {
    information: { name, languages }
  },
  value
} = deepObject;

const extracted = {
  name,
  languages,
  value
};

console.log(extracted);




자바스크립트 기초 문법: 7. spread 와 rest

spread

spread 라는 단어는 ‘펼치다, 퍼뜨리다’ 라는 의미를 뜻하며, 이 문법을 사용하면 객체 혹은 배열을 펼칠 수 있습니다. 예를 들어 다음과 같은 객체들이 있다고 가정해 봅시다.

const button = {
  type: 'button'
};

const largeButton = {
  type: 'button',
  size: 'large'
};

const largeRedButton = {
  type: 'button',
  size: 'large',
  color: 'red'
};

console.log(button); // {"type":"button"}
console.log(largeButton); // {"type":"button","size":"large"} 
console.log(largeRedButton); // {"type":"button","size":"large","color":"red"} 

위 코드를 보면 기존에 선언한 속성은 그대로 둔 채, 새로운 객체를 만들어 기존에 선언한 값을 그대로 사용했습니다.이러한 상황에 사용 할 수 있는 유용한 문법이 spread 입니다. 위 코드를 spread 문법을 사용하면 다음과 같이 작성 할 수 있습니다.

const button = {
  type: 'button'
};

const largeButton = {
  ...button,
  size: 'large'
};

const largeRedButton = {
  ...largeButton,
  color: 'red'
};

console.log(button); // {"type":"button"} 
console.log(largeButton); // {"type":"button","size":"large"} 
console.log(largeRedButton); // {"type":"button","size":"large","color":"red"} 

spread 연산자는 배열에서도 사용 할 수 있습니다.

const animals = ['개', '고양이', '참새'];
const anotherAnimals = [...animals, '비둘기'];
console.log(animals); // ["개","고양이","참새"] 
console.log(anotherAnimals); // ["개","고양이","참새","비둘기"] 

배열에서 spread 연산자를 여러 번 사용 할 수도 있다.

const numbers = [1, 2, 3, 4, 5];

const spreadNumbers = [...numbers, 1000, ...numbers];
console.log(spreadNumbers); // [1, 2, 3, 4, 5, 1000, 1, 2, 3, 4, 5]

rest

rest는 생김새는 spread 랑 비슷한데 역할이 매우 다릅니다. rest는 객체배열, 그리고 함수의 파라미터에서 사용이 가능합니다.

객체에서의 rest

const redLargeButton = {
  type: 'button',
  size: 'large',
  color: 'Red'
};

const { color, ...rest } = redLargeButton;
console.log(color); // Red
console.log(rest); // {type: "button", size: "large"}

rest 는 객체와 배열에서 사용 할 때는 이렇게 비구조화 할당 문법과 함께 사용됩니다. 주로 사용 할 때는 위와 같이 rest 라는 키워드를 사용하게 되는데, 추출한 값의 이름이 꼭 rest 일 필요는 없습니다.

const redLargeButton = {
  type: 'button',
  size: 'large',
  color: 'Red'
};

const { color, ...typeSize } = redLargeButton;
console.log(color); // Red
console.log(typeSize); // {type: "button", size: "large"}

이어서 type 까지 없앤 새로운 객체를 만들고 싶다면 아래와 같이 할 수 있다.

const redLargeButton = {
  type: 'button',
  size: 'large',
  color: 'Red'
};

const { color, ...typeSize } = redLargeButton;
console.log(color); // Red
console.log(typeSize); // {type: "button", size: "large"}

const { type, ...rest } = typeSize;
console.log(type); // button 
console.log(rest); // {size: "large"}

배열에서의 rest

배열 비구조화 할당을 통하여 원하는 값을 밖으로 꺼내고, 나머지 값을 rest 안에 넣을 수 있습니다.

const numbers = [0, 1, 2, 3, 4, 5, 6];

const [one, ...rest] = numbers;

console.log(one); // 0
console.log(rest); // [1, 2, 3, 4, 5, 6]

함수 파라미터에서의 rest

rest 를 함수 파라미터에서 사용 할 수도 있습니다. 예를 들어 우리가 파라미터로 넣어준 모든 값들을 합해주는 함수를 만들어주고 싶다고 가정한다면 아래와 같이 작성할 수 있습니다.

function sum(...rest){
    return rest.reduce((acc, current) => acc + current, 0);
}

const result = sum(1, 2, 3, 4, 5, 6);
console.log(result); // 21

함수 인자와 spread

먼저 헷갈릴 수 있는 인자와 파라미터를 구분해 봅시다.

const myFunction(a) { // 여기서 a 는 파라미터
  console.log(a); // 여기서 a 는 인자
}

myFunction('hello world'); // 여기서 'hello world' 는 인자

함수에서 값을 읽을 때 그 값들은 파라미터라고 부릅니다. 그리고 함수에서 값을 넣어줄 때 그 값들은 인자라고 부릅니다.

배열 안에 있는 원소들을 모두 파라미터로 넣어주고 싶다고 가정해 봅시다.

function sum(...rest) {
  return rest.reduce((acc, current) => acc + current, 0);
}

const numbers = [1, 2, 3, 4, 5, 6];
const result = sum(
  numbers[0],
  numbers[1],
  numbers[2],
  numbers[3],
  numbers[4],
  numbers[5]
);
console.log(result); // 21

위와 같이 작성하면 코드가 길어지고 굉장히 불편합니다. sum함수를 사용 할 때 인자 부분에서 spread 를 사용하면 다음과 같이 깔끔하게 표현이 가능합니다.

function sum(...rest) {
  return rest.reduce((acc, current) => acc + current, 0);
}

const numbers = [1, 2, 3, 4, 5, 6];
const result = sum(...numbers);

console.log(result); // 21




자바스크립트 기초 문법: 8. Scope 에 대한 이해

Scope 란, 우리가 변수 혹은 함수를 선언하게 될 때 해당 변수 또는 함수가 유효한 범위를 의미합니다.

Scope 는 총 3가지 종류 있습니다.

  • Global (전역) Scope: 코드의 모든 범위에서 사용이 가능합니다.
  • Function (함수) Scope: 함수 안에서만 사용이 가능합니다.
  • Block (블록) Scope: if, for, switch 등 특정 블록 내부에서만 사용이 가능합니다.

const 와 var 의 Scope 차이

const value = 'hello!';

function myFunction() {
  const value = 'bye!';
  if (true) {
    const value = 'world';
    console.log('block scope: ');
    console.log(value);
  }
  console.log('function scope: ');
  console.log(value);
}

myFunction();
// block scope:
// world!
// function scope:
// bye!
console.log('global scope: '); // global scope: 
console.log(value); // hello!

const 로 선언한 값은 Block Scope 로 선언이 됩니다. 따라서 if 문 같은 블록 내에서 새로운 변수/상수를 선언하게 된다면 해당 블록 내부에서만 사용이 가능하며, 블록 밖의 범위에서 똑같은 이름을 가진 값이 있다고 해도 영향을 주지 않습니다.

하지만 var는 어떨까요? 

var value = 'hello!';

function myFunction() {
  var = 'bye!';
  if (true) {
    var = 'world';
    console.log('block scope: ');
    console.log(value);
  }
  console.log('function scope: ');
  console.log(value);
}

myFunction();
// block scope:
// world!
// function scope:
// world!
console.log('global scope: '); // global scope: 
console.log(value); // hello!

var 는 Function Scope 로 선언이 되므로 if 문 블록 내부에서 선언한 value 값이 블록 밖의 value 에도 영향을 미치게 됩니다.

(이 글은 2021년 02월에 작성했던 글입니다.)


Related Posts

답글 남기기