JS-ES6 (자바스크립트 정리 1 )

짜스의 하루 ·2024년 5월 7일

지금 까지 공부한 자바스크립트를 정리하거나, ES6문법 에 대해서 공부하는 시간을 가져보기로 한다!

변수

변수란 간단히 값을 담는 그릇 이다. 변수라는 이름에서 알 수 있는이 변수에 담긴 값은 언제든 바뀔 수 있다.
변수를 선언할 때는 let 이라는 예약어(또는 키워드)로 변수를 선언한다.

let username = '이서연';
console.log(username); //이서연이 출력된다.

username = '표원식';
console.log(username); //표원식이 출력된다. 

상수

상수는 ES6에서 새로 생겼다. 상수도 변수와 마찬가지로 값을 할당받을 수 있지만, 한 번 할당한 값을 바꿀 수는 없다.

const username = '이서연';
username = '표원식'; //// Uncaught TypeError: Assignment to constant variable. 라는 오류가 발생한다. 

자바스크립트 프로그래밍시 성능에서 이점을 얻기위해 let 보다 const를 사용하면 좋다.
단! 값이 바뀔 수 있는 경우에는 let을 사용하고, var는 사용하지 말자!

스코프 (Scope)

Scope 를 직역하면 영역, 범위라는 뜻이며, 프로그래밍에서 말하는 스코프는 변수나 함수를 사용할 수 있는 영역을 말한다.

전역 스코프

자바스크립트 최상단에 선언한 변수의 영역은 전역 스코프 이며, 전역 스코프에 선언된 변수를 전역 변수라고 한다.

/* 전역스코프 */
let name = '홍길동';    // 전역변수
let age = 45;         // 전역변수

function printPerson() {
    console.log(`name: ${name}, age: ${age}`);
}

전역 스코프에 선언되어 있는 변수와 함수이다.

블록 스코프

블록 {} 으로 묶인 영역이 블록 스코프이며, 블록안에 선언된 변수는 블록 안에서만 접근 가능하다.
여기서 a는 드래그 한 블록 영역 안에서 사용이 가능하다. 즉, c 를 선언한 곳에서도 a를 사용할 수 있다는 것을 의미한다.
하지만, c는 드래그 한 블록 영역 안에서만 사용이 가능하기 때문에 블록 밖을 벗어난 곳에서는 사용이 불가능하다!


알고 있으면 좋은 내용

var 키워드

ES6 이전에는 변수를 선언할 때는 var 키워드를 사용할 수 있었다. 하지만 var 로 선언한 변수는 다양한 문제를 일으키며, 현재 var 키워드 사용은 하지 않는다고 생각하면 될 것 같다!!

안좋은 이유
- 선언 전에 사용할 수 있다.
- 선언을 여러번 할 수 있다.
- 스코프에 영향을 받지 않는다.

호이스팅 (hoisting)

호이스팅은 코드가 실행되기전 변수나 함수의 선언이 자바스크립트 파일의 최 상단으로 끌어 올려지는 것을 말한다.

변수의 경우 var 로 선언된 변수만 호이스팅이 일어나고, let이나 const는 호이스팅이 일어나지 않는다.

이처럼 함수의 경우, 함수가 선언되기 전에, 출력을 하게 되면,
' 함수가 선언되기 전이니까 오류가 발생하지 않을까요?' 라고 생각할 수도 있겠지만,
아니다! 코드가 실행되기 전, 함수는 먼저 선언이 이루어지기 때문에, 함수에 값을 먼저 할당을 해도, 오류가 발생하지 않고 함수가 정상적으로 실행되는 것을 확인할 수 있다.

Strict Mode

JavaScript의 추가 기능을 사용하면서 발생할 수 있는 일부 실수나 안전하지 않은 기능을 잡아내고, 이를 발생시키지 않도록 하는 것을 목적으로 하는 자바스크립트의 기능이다.

코드 최 상단에 use strict 를 선언해두면 된다.

이렇게 let이나 const를 사용하지 않아도, 자바스크립트 자체에서는 오류가 발생하지 않고 2가 출력된다. 이때,
이렇게 'use strict'를 선언하게 되면,
이러한 오류가 발생하는 것을 확인할 수 있다. 이처럼 오류를 사전에 잡아낼 수 있기 때문에 사용하는 것을 권장한다!


데이터 타입

데이터 타입은 쉽게 말해서 값의 종류를 말한다. 데이터 타입은 크게 기본 타입(Primitive Type)객체 타입(Object Type)으로 구분 할 수 있다.

기본 타입 (Primitive Type)

자바스크립트에서 객체가 아닌 것들이며, 더 이상 작은 단위로 나뉘어 지지 않는 값이며, 그 자체로 변수에 저장 된다. 그리고 이미 생성한 프리미티브 타입 값은 객체, 배열, 함수와 달리 변형할 수 없다.

  • 프리미티브 타입 종류
    • 숫자 (number)
    • 문자열 (string)
    • 불리언 (boolean)
    • null
    • undefined
    • 심볼 (symbol)

숫자

자바스크립트에서 숫자를 표현할 때 number 타입을 사용

let number1 = 12;        // number type
const number2 = 1.2;     // number type

다른 언어와 달리, 숫자 타입은 딱 하나 number 타입을 사용한다.

숫자의 특별한 값

  • Infinity - 양수를 0으로 나누는 경우
  • -Infinity - 음수를 0으로 나눈는 경우
  • NaN - 숫자가 아닌 값을 나누는 경우
const infinity = 1 / 0;             // Infinity 값 할당
const negativeInfinity = 1 / 0;     // -Infinity 값 할당
const nAn = 'not a number' / 0;     // NaN 값 할당

문자열

문자열(string)은 텍스트 데이터 입니다. 자바스크립트에서는 문자열을 표현할 때 작은따옴표(') 큰따옴표(") 백틱(``)을 사용한다.

const name1 = '표원식';     // 싱글쿼터 표현
const name2 = "표투식";      // 더블쿼터 표현
const name3 = `표쓰리식`;    // 백틱 표현

--> 백틱(`)은 ES6에서 도입된 문법이며, 백틱을 사용할 때, 편리하게 사용할 수 있다.

템플릿 문자열

값(value) 을 문자열 안에 써야 할 때, ES6 이전에는 +기호를 통하여 값과 문자열을 연결했다면 ES6에서는 백틱(``) 을 이용하여 편리하게 문자열과 값을 연결할 수 있다.

const name = '이서연';
const age = 27;
console.log('내 이름은 ' + name + ' 입니다. 그리고 나이는 ' + age + '살 입니다.');
// 결과 => 내 이름은 홍길동 입니다. 그리고 나이는 25살 입니다.
console.log(`내 이름은 ${name} 입니다. 그리고 나이는 ${age}살 입니다.`);
// 결과 => 내 이름은 홍길동 입니다. 그리고 나이는 25살 입니다.

${name} 이런식으로 name에 할당한 값을 명시해서 넣어줄 수 있다.

불리언

불리언은 true와 false 두 가지 값 밖에 없는 데이터 타입.

const isProgramer = true;
const idDesigner = false;
if (isProgrammer === true) {
    console.log('나는 프로그래머입니다');
} else {
    console.log('나는 디자이너입니다');
}

로 표현할 수 있다.

심볼

심볼은 유일한 토큰을 나타내기 위해 ES6에서 도입한 새 데이터 타입이다. 심볼은 항상 유일한 값을 의미한다. 우연히 다른 식별자와 혼동해서는 안 되는 고유한 식별자가 필요하다면 심볼을 사용하면 된다.

const mySymbol = Symbol();

이런식으로 선언되는 것을 확인할 수 있다.

null과 undefined

null과 undefined는 자바스크립트의 특별한 타입이다.

  • null 과 undefined 는 둘다 값이 비어있는 상태이다.
  • null - 값이 없는 상태
let message = null; // 값이 빈 상태를 의도적으로 표현

​* undefined - 값을 할당 하지 않은 상태

let message; // 값을 할당하지 않은 상태

객체 타입 (Object Type)

자바스크립트에서 기본 타입을 제외한 모든 타입은 객체 타입이다.

  • 자바스크립트의 내장된 객체
    • Array
    • Date
    • Math
    • Object
    • 이외에 프리미티브 타입을 제외한 모든것이 객체임.
  • 객체 특징
    • 자바스크립트의 객체는 { 이름(key): 값(value) } 의 형태로 프로퍼티(Property)를 저장하는 컨테이너다.
    • 자바스크립트 기본타입은 하나의 값만 가지는 데 비해, 객체 타입은 여러 개의 프로퍼티들을 포함할 수 있다.
    • 객체의 프로퍼티는 값으로 기본 타입 또 다른 객체 그리고 함수를 가질 수 있다.
    • 객체의 프로퍼티가 함수를 가질 때 이를 메서드 라고 부른다.
    • 참조 타입 (Reference Type) 이라고도 한다

객체 예)

const person = {
	name: '이서연',
	age: 25,
	pet: {
		name: '뽀삐',
		age: 2
	},
	sayHello: function() {
		console.log('hello');
	}
};

배열

자바스크립트 배열은 특수한 객체이다. 일반적인 객체와 달리 배열 안에 있는 데이터에는 순서가 있고, 이 순서를 흔히 index 라고 부른다. 배열은 유용한 메서드를 많이 가진 대단히 강력한 데이터 타입을 의미한다.

배열의 생성

  • 배열 리터럴 표기법 (array literal syntax)
const fruits = ['사과', '바나나', '딸기'];
  • 배열 생성자 표기법 (array constructor syntax)
const fruits = new Array('사과', '바나나', '딸기')

--> 보통 실무에서는 리터럴 표기법을 사용하기 때문에 이런게 있다고만 알고 있음 될 것 같다!

배열 접근
--> 대괄호([])를 통하여 배열안의 값에 접근할 수 있다. 그리고 배열의 index는 0부터 시작한다.

const fruits = ['사과', '포도', '딸기', 키위'];
console.log(fruits[0]); //인덱스 0번째 '사과' 출력
fruits[2] ='파인애플'; // 인덱스 2번째인 '딸기'를 파인애플로 바꿀 수 있다. 

자주 사용하는 배열 API(프로퍼티, 메서드)

  • length - 배열의 길이
const fruits = ['사과', '포도', '딸기', 키위'];
console.log(fruits.length) //4출력

배열의 길이를 사용해서 배열의 마지막 항목을 출력할 수 있다

console.log(fruits[fruits.length -1]);

--> 인덱스는 0부터 시작하기 때문에, 마지막 요소를 출력하기 위해서는 length - 1 (4 - 1)를 해야
fruits[3]의 위치한 값을 출력할 수 있다.

  • push - 배열 끝에 항목 추가하기
fruits.push('귤')

배열 마지막에 귤이 추가되는 것을 확인할 수 있다.

  • forEach - 배열의 항목을 순환하며 처리하기
fruits.forEach(i => {
    console.log(i);
});

--> fruits라는 배열을 forEach 메서드를 사용하여 반복하고, 각 요소를 콘솔에 출력한다.
--> forEach는 각 항목을 순회하고, 인덱스도 불러올 수 있다.

fruits.forEach((i, index) => {
	console.log(index, ':', i)
})

첫 번째 매개변수는 현재 요소이고, 두 번째 매개변수는 현재 요소의 인덱스이다. 따라서 코드는 각 요소의 인덱스와 값을 순서대로 콘솔에 출력한다.

  • pop - 배열 끝에 항목 제거하기
fruits.pop()
  • shift - 배열 앞에 항목 제거하기
fruits.shift()
  • unshift - 배열 앞에 항목 추가하기
fruits.unshift('블루베리')
  • indexOf - 배열 안 항목의 인덱스(index) 찾기

const fruits = ['사과', '포도', '딸기', 키위'];
어? 이 배열에서 딸기는 몇번 째 인덱스에 위치해 있는거지 ? 라는 질문에서 사용할 수 있다.

fruits.indexof('딸기');
console.log('index: ', index);  // index:  2
  • splice - 인덱스 위치에있는 항목 제거하기
    splice()메서드는 두개의 매개변수를 가지는데,
    몇번쨰 인덱스부터 몇개를 삭제할래!를 의미한다고 생각하면 된다

const fruits = ['사과', '포도', '딸기', 키위', '파인애플];
이 배열에서 나는 인덱스 1번인 포도부터 2개 삭제할래! (포도부터 2개이므로 포도를 포함해 딸기를 삭제한다는 말을 의미)

fruits.splice(1,2);
console.log(fruits); //  ['사과', 키위', '파인애플];

여기서 응용하자면, 나는 딸기가 어디에 있는지 모르겠는데,
딸기부터 두개 삭제할래!

const fruits = ['사과', '포도', '딸기', '키위', '파인애플'];
const strawberryIndex = fruits.indexOf('딸기');
fruits.splice(strawberryIndex, 1);
console.log(fruits);
  • '딸기' 문자열이 배열 내에서 어디에 위치하는지 확인하기 위해 indexOf 메서드를 사용하여 '딸기'의 인덱스를 찾는다.
  • splice 메서드를 사용하여 strawberryIndex에서부터 1개의 요소를 제거한다. 여기서 strawberryIndex는 '딸기'의 인덱스를 의미한다!

구조 분해 할당 (Distructuring assignment)

구조 분해 할당 문법은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 표현식이다.

  • 일반 - 배열 항목을 개별 변수에 담을 때
const fruits = ['사과', '바나나', '딸기'];
const apple = fruits[0];
const banana = fruits[1];
const strawberry = fruits[2];
  • 구조 분해 할당 - 배열 항목을 개별 변수에 담을 때
const fruits = ['사과', '바나나', '딸기'];
const [apple, banana, strawberry] = fruits;
console.log(apple, banana, strawberry); // 사과 바나나 딸기

const fruits = ['사과', '바나나', '딸기', '수박'];
라는 배열이 있다. 나는 사과만 apple에 할당하고 , 나머지 3개는 other 배열에 담고 싶어!

const [apple, ...others] = fruits;
console.log(others);// ['바나나', '딸기', '수박']

--> ...others는 fruits 배열에서 apple을 제외한 모든 요소를 새로운 배열로 생성한다.

Spread syntax(전개 구문)

Spread는 펼치다라는 뜻으로, Spread syntax는 배열을 할당할 때 참조값을 할당 하는게 아닌 배열안의 항목을 펼치는 방식으로 할당할 수 있다. ... 표기법을 사용하여 사용할 수 있다.

let arr = [1, 'two', 3, 'four'];
let numberArr = [...arr, 5, 'six'];
console.log('numberArr: ', numberArr);
// numberArr:  (6) [1, 'two', 3, 'four', 5, 'six']

Rest parameters

나머지 매개변수 구문(Rest parameters)을 사용하면 함수가 무한한 수의 파라미터를 배열로 받을 수 있다.

const fruits = ['사과', '바나나', '딸기', '수박'];

function print(...items) {
    items.forEach(item => {
        console.log(item);
    });
}

print(...fruits); // 함수 호출
  • ...items는 나머지 매개변수(rest parameter) 구문으로, 함수에 전달된 모든 인자를 배열로 묶는다.
  • 따라서 이 함수를 호출할 때 몇 개의 인자를 전달하든 상관 없이, 이 함수는 모든 전달된 인자를 배열로 묶고, 그 배열의 각 요소를 forEach를 사용하여 반복하면서 각 요소를 콘솔에 출력한다.

배열 복사하기

배열은 객체이기 때문에 참조값을 갖고 있다. 그렇기 때문에 이 값을 다른 배열에 할당하면 같은 참조값을 갖기 때문에 하나의 배열을 변경하면 다른 배열도 같은 참조값을 같고 있기 때문에 결국에는 함게 변경이 된다.

const fruits = ['오렌지', '포도', '사과', '바나나', '딸기'];
const copyFruits = fruits;
copyFruits.pop();
console.log('fruits: ', fruits);   // ['오렌지', '포도', '사과', '바나나']
console.log('copyFruits: ', copyFruits); // ['오렌지', '포도', '사과', '바나나']

깊은 복사가 일어날 때에는 언제일까?
1 ) 스프레드 문법

const fruits = ['오렌지', '포도', '사과', '바나나', '딸기'];
const copy = [...fruits];
copy.pop();                        // 끝에 항목 제거
console.log('fruits: ', fruits);   // ['오렌지', '포도', '사과', '바나나', '딸기']
console.log('copyFruits: ', copy); // ['오렌지', '포도', '사과', '바나나']

--> 스프레드 문법([...array])을 사용하여 배열을 복사하면 깊은 복사(deep copy)가 이루어진다. 이는 원래 배열과 복사본 사이에 완전히 독립적인 새로운 배열이 생성된다는 것을 의미한다.

2 ) Array.from

const fruits = ['오렌지', '포도', '사과', '바나나', '딸기'];
const copyFruits = Array.from(fruits);
copyFruits.push('파인애플');
console.log('fruits: ', fruits);   // ['오렌지', '포도', '사과', '바나나', '딸기']
console.log('copyFruits: ', copyFruits); // ['오렌지', '포도', '사과', '바나나', '파인애플']

--> Array.from은 배열이나 유사 배열 객체를 복사하여 새로운 배열을 생성한다. 이때 깊은 복사가 이루어지므로 원래 배열과 복사본 배열은 서로 독립적으로 작동한다.

3 ) slice

배열의 일부분을 추출하여 새로운 배열을 반환한다. 이 메서드는 원본 배열을 변경하지 않는다. 대신, 추출된 일부분을 담은 새로운 배열을 반환한다.

slice() 메서드는 두 개의 매개변수를 받을 수 있습니다. 첫 번째 매개변수는 추출을 시작할 인덱스이고, 두 번째 매개변수는 추출을 종료할 인덱스이다. 두 번째 인덱스에 해당하는 요소는 추출되지 않는다!

const fruits = ['오렌지', '포도', '사과', '바나나', '딸기'];
const copyFruits = fruits.slice(0, 4);
console.log('fruits: ', fruits);   // ['오렌지', '포도', '사과', '바나나', '딸기']
console.log('copyFruits: ', copyFruits); // ['오렌지', '포도', '사과', '바나나']

fruits.slice(0, 4)는 fruits 배열의 인덱스 0부터 3까지(4는 포함하지 않음)의 요소를 추출하여 새로운 배열을 생성한다. 따라서 '오렌지', '포도', '사과', '바나나'가 추출되어 새로운 배열이 만들어진다.

  • 그런 다음 fruits와 copyFruits를 출력하면 fruits는 변경되지 않고, copyFruits에는 새로운 배열이 할당되어 '오렌지', '포도', '사과', '바나나'를 가지고 있는 것을 확인할 수 있다!

쉽게 설명하자면, 나는인덱스 0번부터 인덱스 4번 전까지 출력할거야! 라고 생각하고 있으면 될 것 같다!

profile
2024. 01. 02 ~ 백앤드 공부 시작, 2024. 04.01 ~ 프론트 공부 시작

0개의 댓글