안녕하세요!

FE 개발자 유진주입니다.

Web/React

[Udemy React 완벽 가이드] 섹션 2: 자바스크립트 새로고침

ypearl 2023. 7. 27. 15:40

변수 let과 const

var: 자바스크립트에서 변수 생성

(ES6에는 var도 물론 있지만, let과 const 사용을 권장)

 

- let: 값을 수정할 수 있는 변수를 선언할 때 사용 (새로운 var)

- const: 한번 지정하면 정대 변하지 않는 값인 상수를 선언할 때 사용

(새로운 값을 할당할 수 없는 키워드. 만약 실수로 값을 재할당하도록 코드를 작성했다면, 오류 발생🚨)

const myName = 'Max';
console.log(myName);
myName = 'Manu';
console.log(myName);

<Console창>
"Max"
"Manu"	// var의 경우
"Max"
"Manu"	// let의 경우 (var과 결과 동일)
"Max"
"error"	// const의 경우 (두 번째 console.log에서 에러발생)
	: 상수 변수에 값을 재할당하려고 했기 때문
"TypeError: Assignment to constant variable.
    at vagulewoge.js:4:8
    at https://static.jsbin.com/js/prod/runner-4.1.8.min.js:1:13924
    at https://static.jsbin.com/js/prod/runner-4.1.8.min.js:1:10866"

 

Arrow Functions (화살표 함수)

: 일반적 자바스크립트 함수 키워드 function로 달리,

const,가 선언되고 오른쪽에는 등호(=)가 있는 또다른 구문

[ 장점 ]

- 키워드 function을 생략했기에 일반적인 함수보다 짧다.

- 키워드 this로 인해 생겼던 많은 문제를 해결해준다.

[방법 1]
function printMyName(name){
  console.log(name);
}

printMyName('Max');

[방법 2]✨
: 인수가 딱 1개인 경우에만 괄호 생략 가능
const printMyName = name => {
  console.log(name);
}

printMyName('Max');

: 인수가 없거나(0개), 2개 이상인 경우에는 괄호 생략 불가
const printMyName = (name, age) => {
  console.log(name, age);
}

printMyName('Max', 28);
--------------------------------------------------------
예시)
다음과 같은 코드를
const multiply = (number) => {
  return number*2;
}

console.log(multiply(2));

아래와 같이 간단하게 표현 가능
const multiply = number => number*2;
console.log(multiply(2));

 

Exports & Imports (모듈)

- Modules(모듈)

: 문장을 내보내고 가져오는, 자바스크립트 파일 안에 있는 것

 

클래스 (Classes)

:  클래스는 class 키워드로 정의되고, property와 method를 가질 수 있다.

- 메소드(Method): 클래스에 정의한 함수

- 프로퍼티(Property): 클래스에 정의한 변수

 

- new 키워드로 클래스의 인스턴스를 생성

- 상속: 다른 클래스에 있는 프로퍼티와 메소드를 상속해

           잠재적으로 새로운 프로퍼티와 메소드를 추가함.

class Human{
  constructor(){
    this.gender = 'male';
  }
  
  printGender(){
    console.log(this.gender);
  }
}


class Person extends Human{ // extends 키워드를 사용해서 Human 클래스를 상속받아 확장
  constructor(){
    super();	// 서브 클래스에서는 super 생성자를 먼저 호출해야 함
    this.name='Jinju';
    this.gender = 'female';	// Human 클래스의 printGender()를 호출했지만, Person 클래스에서 확장되었기 때문에 결과값으로 female이 출력됨
  }
  
  printMyName(){
    console.log(this.name);
  }
}

const person = new Person();
person.printMyName();
person.printGender();

[Console창]
"Jinju"
"female"

 

 프로퍼티(Property) & 메소드(Method)

- 프로퍼티(Property)

: 클래스와 객체에 추가되는 변수같은 것

- 메소드(Method)

: 클래스와 객체에 추가되는 함수같은 것

위의 코드를 차세대 자바스크립트 구문으로 변경한 것

 

스프레드(Spread) & 레스트 연산자(Rest Operators)

: 점 3개(...)으로 이루어진 연산자

(어디에 사용하는지에 따라 스프레드 또는 레스트라 부름)

 

- 스프레드 연산자(Spread Operators)

: 배열의 원소나 객체의 프로퍼티를 나누는데 사용됨

예제1🍕: oldArray 배열에 있는 모든 원소들을 새로운 배열에 추가하고,
거기에 원소 1과 2를 더 추가하는 경우

const newArray = [...oldArray, 1, 2];

예제2🍔: newProp와 함께 중괄호를 사용해서 새로운 객체를 만드는데
...oldObject로 oldObject의 모든 프로퍼티와 값을 꺼내서
새 객체의 키 값으로 newProp에 추가한다.

const newObject = {...oldObject, newProp: 5};

* 참고로 oldObject가 새로운 프로퍼티를 가지게 되면 여기 있는 newProp에 덮어씌워진다.
이를 통해 우리가 가지고 있는 프로퍼티가 우선권을 갖게 된다.

- 레스트 연산자(Rest Operators)

: 함수의 인수 목록을 배열로 합치는데 사용됨

예제🍟: 매개변수를 무제한으로 받는 sortArgs
function sortArgs(...args){
	return args.sort();
}

 

✨스프레드 연산자의 사용
예) 아주 쉽게 배열을 복사하거나,
안전하게 이전 객체를 복사해 객체에 프로퍼티를 추가하는 작업 등

const numbers = [1, 2, 3];
const newNumbers = [...numbers, 4];

console.log(newNumbers);

[Console 창]
[1, 2, 3, 4]	// 모든 원소들을 배열로 전달받음

✨스프레드 연산자의 사용: 객체의 프로퍼티 나누기

✨리스트 연산자의 사용

const filter = (...args) => {
  return args.filter(el => el === 1);	// 등호 3개: 타입과 값이 같은지 체크
}

console.log(filter(1,2,3));

[Console 창]
[1]

 

구조분해할당 (Destructuring)

: 배열의 원소나 객체의 프로퍼티를 추출해서 변수에 저장할 수 있도록 해준다.

(≠ 스프레드 연산자)

? 스프레드는 모든 원소와 프로퍼티를 가져와서 새 배열이나 객체 등에 전달하지만,

구조분해할당은 원소나 프로퍼티를 하나만 가져와서 변수에 저장한다.

🤍 배열(Array) Destructuring
[a, b] = ['Hello', 'Max']
console.log(a) // Hello
console.log(b) // Max

🤍 객체(Object) Destructuring
{name} = {name: 'Max', age: 28}
console.log(name) // Max
console.log(age)  // undefinded (객체에서 이 age를 추출하지 않기 때문)
const numbers = [1,2,3];
[num1, num2] = numbers;
console.log(num1, num2);

[Console 창]
1
2

const numbers = [1,2,3];
[num1, , num3] = numbers;
console.log(num1, num3);

[Console 창]
1
3

 

참조형 및 원시형 데이터 타입

- 기본형 자료 타입: number, string, boolean

ㄴ 재할당하거나 변수를 다른 변수에 저장할 때마다 값을 복사한다.

- 참조형 자료 타입: 객체(object), 배열(array)

const person = {
  name: 'Max'
};

const secondPerson = person;

person.name = 'Manu';

console.log(secondPerson);

[Console 창]
[object Object] {
  name: "Manu"	// person의 name을 변경하면, 자동적으로 secondPerson의 이름도 바뀜 (포인터)
}

🚨 만약 재할당한다면, 값이 아닌 포인터를 복사하는 것이다.

따라서 진짜로 '복사'하고 싶다면, 새로운 객체를 생성해서 전체 객체를 복사하는 것이 아니라

프로터피를 복사해야 한다.

 

배열 함수 새로고침

: filter, sort, map 등

⚠ map() : 예전 값을 새 값으로 반환

const numbers = [1,2,3];

const doubleNumArray = numbers.map((num) => {
  return num*2;
});

console.log(numbers);	// [1, 2, 3]
console.log(doubleNumArray);	// [2, 4, 6]

배열 관련 함수들은 각 원소들에서 실행되는 함수들을 갖고 있으며,

차세대 자바스크립트는 아니고 일반적인 자바스크립트이다.

 

 

 

 

 

 

 


(*다음 내용은 <Udemy React 완벽 가이드> 강의에서 제공한 요약본입니다.)

차세대 JavaScript - 요약

이 모듈에서, 저는 몇몇 핵심 차세대 자바스크립트 기능들에 대한 간략한 소개를 해 드렸습니다. 물론 이 과정에서 여러분들이 자주 보시게 될 것들에 초점을 맞추었죠. 여기 간략한 요약이 있습니다!

let & const

let 에 대해 더 읽어보기: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

const에 대해 더 읽어보기:: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const

let 과 const 는 기본적으로 var 를 대체합니다. 여러분은 var 대신 let 을 사용하고, var  대신 const를 사용하게 됩니다. 만약 이 "변수"를 다시 할당하지 않을 경우에 말이죠 (따라서 효과적으로 constant로 변환합니다).

ES6 Arrow Functions

더 읽어보기: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Arrow function은 JavaScript 환경에서함수를 생성하는 또 다른 방법입니다. 더 짧은 구문 외에도 this 키워드의 범위를 유지하는데 있 이점을 제공합니다 (여기를 보세요).

Arrow function 구문은 낯설게 보일 수 있으나 사실 간단합니다.

function callMe(name) {

    console.log(name);

}

또한 다음과 같이 작성할 수도 있습니다:

const callMe = function(name) {

    console.log(name);

}

이렇게 됩니다:

const callMe = (name) => {

    console.log(name);

}

중요: 

arguments가 없는 경우, 함수 선언시 빈 괄호를 사용해야 합니다:

const callMe = () => {

    console.log('Max!');

}

정확히 하나의 argument가 있는 경우, 괄호를 생략할 수 있습니다:

const callMe = name => {

    console.log(name);

}

value를 return할 때, 다음과 같은 숏컷을 사용할 수 있습니다:

const returnMe = name => name

이것은 다음과 같습니다:

const returnMe = name => {

    return name;

}

Exports & Imports

React 프로젝트에서 (그리고 실제로 모든 최신 JavaScript에서), 모듈이라 불리는 여러 자바스크립트 파일들에 코드를 분할합니다. 이렇게 하면 각 file/ 모듈의 목적을 명확하게 하고 관리가 용이하게 합니다.

다른 파일의 기능에 계속 액세스하려면 export  (available하게 하기 위해) 및 import 엑세스를 확보하기 위해) statements가 필요합니다.

두 가지 유형의 export가 있습니다: default (unnamed)와 named 입니다.

default => export default ...; 

named => export const someData = ...; 

default exports를 다음과 같이 import 할 수 있습니다.

import someNameOfYourChoice from './path/to/file.js'; 

놀랍게도, someNameOfYourChoice  전적으로 여러분에게 달려 있습니다.

Named exports는 이름으로 import되어야 합니다:

import { someData } from './path/to/file.js'; 

파일 하나는 오직 하나의 default와 무한한 named exports를 가질 수 있습니다. 하나의 default를 같은 파일 내에서 named exports와 믹스할 수 있습니다.

named exports를 import할 때, 다음 구문을 이용해 한 번에 모든 named exports를 import할 수 있습니다.

import * as upToYou from './path/to/file.js'; 

upToYou 는 모든 exported 변수/함수를 하나의 자바스크립트 객체에 모읍니다. 예를 들어, export const someData = ...  (/path/to/file.js ) 이와 같이 upToYou 에 액세스 할 수 있습니다: upToYou.someData .

Classes

Classes는 constructor 함수와 prototypes를 대체하는 기능입니다. 자바스크립트 객체에 blueprints를 정의할 수 있습니다.

예시:

class Person {

    constructor () {

        this.name = 'Max';

    }

}

 

const person = new Person();

console.log(person.name); // prints 'Max'

위의 예시에서, class뿐 만 아니라 해당 class의 property (=> name) 이 정의됩니다. 해당 구문은, property를 정의하는 "구식" 구문입니다. 최신 자바스크립트 프로젝트에서는 (이 코스에서 사용된 것처럼), 다음과 같은 보다 편리한 정의 방법을 사용해 class property를 정의합니다:

class Person {

    name = 'Max';

}

 

const person = new Person();

console.log(person.name); // prints 'Max'

메소드를 정의할 수도 있습니다. 다음과 같이 말이죠:

class Person {

    name = 'Max';

    printMyName () {

        console.log(this.name); // this is required to refer to the class!

    }

}

 

const person = new Person();

person.printMyName();

혹은 이와 같이 할 수도 있습니다:

class Person {

    name = 'Max';

    printMyName = () => {

        console.log(this.name);

    }

}

 

const person = new Person();

person.printMyName();

두 번째 접근 방식은 all arrow function과 같은 이점이 있습니다: this키워드가 reference를 변경하지 않습니다.

class 사용시 inheritance를 사용할 수도 있습니다.

class Human {

    species = 'human';

}

 

class Person extends Human {

    name = 'Max';

    printMyName = () => {

        console.log(this.name);

    }

}

 

const person = new Person();

person.printMyName();

console.log(person.species); // prints 'human'

Spread & Rest Operator

Spread 와 rest operator는 사실 같은 구문을 사용합니다: ... 

맞습니다, 연산자입니다 - 점 세개죠. 이것을 사용해 spread로 사용할지 rest operator로 사용할지 결정합니다.

Spread Operator 사용하기:

Spread operator는 배열에서 요소들을 가져오거나 (=> 배열을 요소들의 리스트로 분해) 객체에서 속성을 가져옵니다.

두 가지 예시가 있습니다:

const oldArray = [1, 2, 3];

const newArray = [...oldArray, 4, 5]; // This now is [1, 2, 3, 4, 5];

객체에 spread operator를 사용한 예시입니다:

const oldObject = {

    name: 'Max'

};

const newObject = {

    ...oldObject,

    age: 28

};

그러면 newObject는 다음이 될 것입니다.

{

    name: 'Max',

    age: 28

}

sperad operator는 배열과 객체를 복제하는데 매우 유용합니다. 둘 다  (primitives가 아닌) reference 유형이기 때문에, 안정적으로 복사를 하는게 어려울 수 있습니다. (복사된 원본에 future mutation 발생 방지). Spread operator로, 객체나 배열의 복사본 (shallow!)을 쉽게 얻을 수 있습니다.

 

Destructuring

Destructuring을 사용하면 배열이나 객체의 값에 쉽게 엑세스할 수 있고 변수에 할당할 수 있습니다.

한 배열의 예시입니다:

const array = [1, 2, 3];

const [a, b] = array;

console.log(a); // prints 1

console.log(b); // prints 2

console.log(array); // prints [1, 2, 3]

다음은 객체의 예시입니다:

const myObj = {

    name: 'Max',

    age: 28

}

const {name} = myObj;

console.log(name); // prints 'Max'

console.log(age); // prints undefined

console.log(myObj); // prints {name: 'Max', age: 28}

Destructuring은 인자를 가진 함수를 작업할 때 매우 유용합니다. 이 예시를 보시죠:

const printName = (personObj) => {

    console.log(personObj.name);

}

printName({name: 'Max', age: 28}); // prints 'Max'

여기서, 함수내 name만을 print하고 싶지만 함수에 완전한 person 객체를 보내고 있습니다. 당연히 이것은 문제가 되지 않지만 personObj.name을 이 함수내에서 호출해야만 합니다. 이 코드를 destructuring으로 압축시켜 보겠습니다.

const printName = ({name}) => {

    console.log(name);

}

printName({name: 'Max', age: 28}); // prints 'Max')

위와 동일한 결과를 얻지만 코드가 줄었습니다. Destructuring을 통해, name property를 가져와 name 이라는 이름의 변수/인수에 저장하고 함수 본문에서 사용할 수 있습니다.


JS Array functions

차세대 자바스크립트는 아니지만 중요.
다음과 같은 자바스크립트 array 함수가 있음: map() , filter() , reduce()