[TIL] 내일배움캠프 React 과정 2022.11.29

Today I Learned

  • javascript 기초 문법 공부
  • javascript 심화 강의 수강

 

javascript 기초 문법

선언되지 않은 변수를 참조한다면?

Reference error를 일으키게 된다.

console.log(foo);
// ReferenceError: foo is not defined

 

javascript 함수 기본 구조

function 함수이름(인자1, 인자2, 인자3) {
  // 명령문
}

함수이름(인수1, 인수2, 인수3); // 명령문에 있는 내용을 실행한다.
  • 인자(Parameter 또는 매개변수)란 함수를 호출할 때 전달받기 위해 지정한 변수를 뜻한다.
  • 인수(Argument)란 인자에 전달하는 값 그 자체를 의미한다.
  • 함수는 return 키워드로 값을 반환할 수 있다.

 

 

javascript에서 함수 만드는 방법

함수 선언식 (Function keyword)

function sayHello () {
	return "hello, world!"
}

 

함수 표현식(Function keyword)

const sayHello = function(){
	return "hello, world!"
}

 

화살표 함수(Arrow function)

// 방식 1
const sayHello = () => {
	return "hello world!"
}

// 방식 2-암시적 반환
// 함수가 반환하는 값을 한 줄로 표현할 수 있는 경우 return을 생략 가능
const sayHello = () => "hello world!"

 

Arrow function - 익명 함수

간단한 함수를 일회성으로만 사용할 때 화살표 함수에 익명 함수를 사용할 수 있다.

// 예시 1 - 기본적인 함수 표현 방식
const sayHelloOnClick = () => {
	console.log('hello friend')
}
<App onClick={sayHelloOnClick} />

// ❗️ 예시 1 - 익명 함수
<App onClick={() => console.log('hello friend')} />


// 예시 2 - 기본적인 함수 표현 방식
const ReturnItem = (item) => {
	return <div>{item}</div>
}
{array.map(ReturnItem)}

// ❗️ 예시 2 - 익명 함수
{array.map((item)=> <div>{item}</div>))}

 

 

객체와 배열 구조분해 할당

구조분해 할당을 사용하지 않을 때

// user가 객체일 때
const getUserName = (user) => {
	return user.name
}

// user가 배열일 때
const getUserName = (user) => {
	return user[0]
}

 

구조분해 할당을 사용했을 때

// 객체일 때
const getUserName = ({name, age}) => {
	return name;
};

// 배열일 때
const getUserName = ([name, age]) => {
	return name
};

 

 

전개 구문(spread operator)이란?

기존에 있는 객체나 배열의 내용을 그대로 가져오거나 새로운 값을 덧붙여서 새로운 객체나 배열을 생성할 수 있다. 기존의 데이터 (객체나 배열)에는 전혀 영향을 주지 않고 복사해서 새로운 것을 만든다.

const box = {size: "big", color: "red"};

const newBox = { ...box}; // {size: "big", color: "red"}
const newBlueBox = {...box, color: "blue" }; // {size: "big", color: "blue"}

 

 

자주 사용하는 메서드

map()

배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.

const array1= [1,4,9,16];

//map 사용
const map1 = array1.map(x=>x*2);

//함수가 적용된 결과로 새로운 배열을 반환한다.
console.log(map1); //[2, 8, 18, 32]

 

fileter()

주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.

const fruits= ['사과', '귤', '배', '감', '바나나', '키위'];

//filter 사용
const result = fruits.filter(fruit => fruit.length > 2);

//함수가 적용된 결과로 새로운 배열을 반환한다.
console.log(result); //['바나나']

 

 

javascript 심화 강의

데이터 타입 구분하기

  • 기본형 데이터 : 값이 담긴 주소값을 바로 복제 (불변값)
  • 참조형 데이터 : 값이 담긴 주소 값들로 이루어진 묶음을 가리키는 주소 값을 복제 (가변값)

 

참고 https://velog.io/@imjkim49/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85-%EC%A0%95%EB%A6%AC

 

 

 

데이터 타입을 이해하기 위해 필요한 배경지식

비트(bit): 0과 1을 가지고 있는 작은 메모리 조각 (모든 비트가 각자의 고유 식별자를 가지고 있음)

바이트(byte): 비트가 8개씩 모인 묶음 1byte = 8bit (검색의 효율성이 좋아짐)

비트의 무수히 많은 조각의 모여서 메모리가 됨

 

식별자 = 변수명

변수 = 데이터 (변경 가능한 데이터가 담기는 공간)

var a = 3;
// a -> 식별자
// 3 -> 변수

 

결론: 모든 데이터는 byte 단위의 식별자인 메모리 주소 값을 통해서 서로 구분이 된다.

 

 

 

기본형 데이터의 불변성 이해하기

var a = 'abc';
a = a + 'def';

위와 같은 구조에서 a의 값이  'abc'에서 'abcdef'로 교체되는 것이 아니라 'abc' 외에 'abcdef'라는 데이터가 별개로 생성된 후 이것이 식별자 a에 다시 할당되는 것이다. 결론적으로 데이터 영역의 메모리가 변경되지는 않았다!

+) 더 이상 사용하지 않는 데이터 'abc'는 정리된다. -> 이것이 가비지 컬렉팅

 

 

 

참조형 데이터의 가변성 이해하기

var obj1 = {
a: 1,
b: 'bbb',
};
obj1.a = 2;

참조형 데이터의 변수 할당 과정의 특징 : 객체의 변수(프로퍼티) 영역이 별도로 존재함

a의 값을 2로 변경할 때 객체 obj1를 위한 별도의 영역에서 a의 데이터가 1에서 2로 교체됨 -> 가변한다

 

 

 

변수 복사의 비교

//기본형 데이터
var a = 10;
var b = a;

//참조형 데이터
var obj1 = { c: 10, d: 'ddd' };
var obj2 = obj1;

b = 15;
obj2.c = 20;

// 결과
a = 10;
b = 15;
obj1 =  { c: 20, d: 'ddd' };
obj2 =  { c: 20, d: 'ddd' };

변수 복사 후 값을 변경했을 때 결과

a !== b

obj1 === obj2

 

참조형 데이터가 ‘가변값’이라고 할 때의 ‘가변’은 참조형 데이터 자체를 변경할 경우가 아니라, 그 내부의 프로퍼티를 변경할 때 성립함. 참조형 데이터를 복사한 후 복사한 데이터를 수정하면 기존의 데이터도 영향을 받는다.

 

 

 

불변 객체

  • 얕은 복사 : 바로 아래 단계의 값만 복사 —> 문제점 : 중첩된 객체의 경우 참조형 데이터가 저장된 프로퍼티를 복사할 때 주소 값만 복사함 
  • 깊은 복사 : 내부의 모든 값들을 하나하나 다 찾아서 모두 복사하는 방법 -> 참조형 데이터를 불변값으로 사용 가능
var copyObjectDeep = function(target) {
    var result = {};
    if (typeof target === 'object' && target !== null) {
   	 for (var prop in target) {
    		result[prop] = copyObjectDeep(target[prop]);
    	}
    } else {
   	 result = target;
    }
    return result;
}

//결과 확인
var obj = {
    a: 1,
    b: {
        c: null,
        d: [1, 2],
    }
};

var obj2 = copyObjectDeep(obj);
obj2.a = 3;
obj2.b.c = 4;
obj2.b.d[1] = 3;

abj1 = { a: 1, b: { c: null, d: [ 1, 2 ] } }
abj2 = { a: 3, b: { c: 4, d: { '0': 1, '1': 3 } } }

재귀 함수를 이용하면 객체의 프로퍼티 중 기본형 데이터는 그대로 복사하고 참조형 데이터는 다시 그 내부의 프로퍼티를 복사하면서 완벽히 다른 객체를 반환할 수 있다.

 

 

 

javascript 엔진에서 undefined를 자동 반환하는 경우

var a;
console.log(a);

var obj = { a: 1 };
console.log(obj.a);
console.log(obj.b);

var func = function() { };
var c = func();
console.log(c);

1. 변수에 값이 지정되지 않은 경우, 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때

2. .이나 []로 접근하려 할 때, 해당 데이터가 존재하지 않는 경우

3. return 문이 없거나 호출되지 않는 함수의 실행 결과

 

 

 

회고

오전에는 공부하다 말았던 자바스크립트 기초 문법을 빠르게 공부하고 오후부터는 원장 튜터님의 자바스크립트 심화 강의를 들었다. 오늘은 왜인지 집중이 잘 안 돼서 데이터 타입 챕터밖에 못 들었는데 은근히 어려운 거 같다. 이럴 땐 모든 것을 이해하려고 하기보다는 일단 최대한 집중하며 강의를 듣는다. 팀원들과 열심히 팀프로젝트 하다가 혼자 강의 들으려니까 좀 지루하기도 하다. 내일은 실행 컨텍스트와 THIS 강의를 듣는 것을 목표로 하고 오늘 하루를 마무리한다! WIL만 쓰고 자야지...