728x90
국민내일배움카드로 국비지원받고 프론트엔드 학습
열공 챌린지 5주차

 

🎥 목차

더보기

1. 목표

2. 알게된 점

3. 좋았던 점

 

🚀 목표

패스트 캠퍼스에서 학습주차별로 구분지어줬기 때문에, 5주차 학습강의 듣기가 학습 목표이다.

 

 

💡 알게된 점

즉시 실행 함수

함수를 선언하고, 함수를 실행할때 기명함수를 호출하는 방식말고 선언하는 즉시 바로 실행하도록 만들 수 있다.

# 기명함수 호출
const numberCall = () => {
	console.log(123)
})
numberCall()

# 즉시 실행 함수
(const numberCall = () => {
	console.log(123)
}())

 

호이스팅

콘솔창에 14라고 찍혀서 나온다.

let, const 키워드로 선언한 변수나 const로 선언한 함수는 호이스팅이 적용되지 않는다.

 

그러나, function 키워드로 선언한 함수, var 키워드로 선언한 변수는 호이스팅이 적용이 된다.

 

prototype

강의에서는 function으로 메서드를 정의했는데, 나는 클래스로 메서드를 정의하는 것이 편해 클래스로 코드를 작성하려고한다.

# class 안에 메소드 정의
class User() {
	this.firstName = firstName;
    this.lastName = lastName;
    getFullName: function () {
    	return `${this.firstName} ${this.lastName}`
    }
}

# 위의 class와 동일한 기능을 가진 class 정의
# prototype으로 정의
class User() {
	this.firstName = firstName;
    this.lastName = lastName;
}

User.prototype.getFullName = function () {
    	return `${this.firstName} ${this.lastName}`
    }

 

this

일반 함수

global scope 에서 사용될 때 this 는 전역 객체를 가리킵니다.(window 객체)
함수에서 사용될 때에도 this 는 전역 객체를 가리킵니다.
객체에 속한 메소드에서 사용될 때 this 는 메소드가 속한 객체를 가리킵니다.
객체에 속한 메소드의 내부함수에서 사용될 때 this 는 전역 객체를 가리킵니다.
생성자에서 사용될 때 this 는 이 생성자로 인해 생성된 새로운 객체를 가리킵니다.

 

화살표 함수

화살표 함수는 익명 함수로만 만들 수 있습니다.
화살표 함수는 생성자로 사용할 수 없습니다.
화살표 함수는 스스로의 this, argument 를 가지지 않습니다.
함수가 정의된 스코프에 존재하는 this 를 가리킵니다.
화살표 함수는 생성될 때 this 가 결정됩니다.
화살표 함수가 어떻게 사용되건, 호출되건, this 는 바뀌지 않습니다.
const nameCall = {
	name: 'Jhon',
    normal: function () {
    	console.log(this.name)
    },
    arrow: () => {
    	console.log(this.name)
    }
}

nameCall.normal();		// Jhon
nameCall.arrow();		// undefined

# function 키워드로 정의한 함수는, 메서드가 호출된 위치에서 this가 정의된다.
# nameCall 객체에서 normal 메서드를 호출한다.
# 즉, this는 nameCall이고, this.name은 nameCall.name이다.
# 그래서 Jhon이 출력된다.

# arrow 함수로 정의된 경우에는, 메서드가 호출된 위치에 상관없이 arrow 함수가 정의된 위치에서 this가 정의된다.
# arrow 함수로 정의된 경우에는, 자신이 선언된 함수 범위의 this를 정의한다.
# arrow 함수를 감싸고 있는 함수는 없으므로, undefined가 출력된다.

 

string.match(Regex)

문자열 메소드인 match에 매개변수로 정규표현식을 입력하여, 정규표현식에 일치하는 문자열을 배열로 반환한다.

 

배열안의 데이터

배열 안에 있는 데이터를 공식 단어로는 element라고 한다.

 

비공식 단어로는 item이라고도 한다.

 

array.forEach(element, index, array){...}

배열은 forEach 메소드를 이용하여, 반복적으로 element에 접근할 수 있다.

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

numbers.forEach(element, index, array) {
	console.log(element, index, array)
}

// 1 0 [1,2,3,4,5]
// 2 1 [1,2,3,4,5]
// 3 2 [1,2,3,4,5]
// 4 3 [1,2,3,4,5]
// 5 4 [1,2,3,4,5]
// 세번째 매개변수인 array는 잘 사용하지 않는다.

 

forEach 함수는 return되는 값이 없다.

 

array.map(element, index){...}

map함수는 forEach와 다르게, return되는 값이 있다.

array의 element수 만큼 반복하고 return된 값으로 배열을 만든다.

const numbers = [1,2,3]

const a = numbers.forEach(element, index, array) {
	console.log(element, index, array)
}
console.log(a)		// undefined

// map 함수는 새로운 배열로 반환한다.
const b = numbers.forEach(element, index) {
	return `${element}-${index}`
}
console.log(b)		// ['1-0', '2-1', '3-2']

 

화살표 함수 return 생략

화살표 함수가 1개의 데이터만을 return 할 경우, return 키워드와 중괄호를 생략할 수 있다.

const fruits = ['apple', 'banana', 'cherry']

const result = fruits.map((element, index)=> `${element}-${index}`)
// ['apple-0', 'banana-1', 'cherry-2']

# 만약 객체데이터를 반환할 경우에는 소괄호를 이용하여 반환해야한다.
const result = fruits.map((element, index)=> ({id: index, fruit: element}) )
// [{id: 0, fruit: 'apple'}, {id: 1, fruit: 'banana'}, {id: 2, fruit: 'cherry'}]

 

배열 메소드 : splice(index, removeCount, addCount)

const numbers = [1,2,3,4]
numbers.splice(2, 2)

console.log(numbers)   // [1,2]

numbers.splice(2,0,999)

console.log(numbers)   // [1,2,999]

 

구조 분해 할당

데이터를 구조 분해 할당으로 데이터를 선언할때, 변수명을 변경하고 싶다면 콜론( : ) 뒤에 변수명을 적는다.

const user = {
	name: 'Jhon',
    age: 73,
    gender: male
}

const {name, age, gender: sex} = user

console.log(name, age, sex)  // Jhon 73 male

 

불변성

원시 데이터: String, Number, Boolean, undefined, null데이터가 이미 메모리 주소에 있다면, 새로 메모리를 할당하지 않고 이미 존재하는 메모리 주소를 가리킨다.

let a = 1 // 주소 1
let b = 3 // 주소 2
let c = 1 // 주소 1
let d = 4 // 주소 3
let e = 3 // 주소 2

 

참조형 데이터 : Object, Array, Function

 

얕은 복사, 깊은 복사

얕은 복사는 참조형 데이터 하나만 복사하고, 참조형 데이터 안에 또다른 참조형 데이터는 복사하지 않고 메모리 주소를 공유한다.

 

얕은 복사로 원본을 복제한 경우, 원본 데이터의 값이 변경된다면 복제본도 값이 변경된다.

 

얕은 복사를 하는 방법은 할당 연산자( = )를 이용하면 된다.

const fruits = ['apple', 'banana', 'cherry', 'orange']
const shallowCopy = fruits

fruits.push('test')
shallowCopy === fruits  // true

 

깊은 복사는 참조형 데이터 안에 모든 참조형 데이터를 복사하여, 다른 메모리 주소를 할당한다.

 

깊은 복사로 원본을 복제한 경우, 원본 데이터의 값이 변경되도 복제본의 값이 변하지 않는다.

 

깊은 복사를 하는 방법은 전개 연산자(...)를 이용하면 된다.

# 참조형 데이터안에 원시 데이터만 있는 경우, 전개연산자를 이용하면 깊은 복사가 된다.
const fruits = ['apple', 'banana', 'cherry', 'orange']
const shallowCopy = [...fruits]

fruits.push('test')
shallowCopy === fruits  // false

 

여기서 중요한 점은, 전개 연산자로 깊은 복사를 해도 원본 데이터 안에 또다른 참조형 데이터가 있는 경우에는 얕은 복사가 된다.

즉, 참조형 데이터 안에 참조형 데이터가 있으면 깊은 복사를 의도하여 복사해도 얕은 복사가 이루어진다.

# 참조형 데이터안에 참조형 데이터가 있는 경우, 전개연산자를 이용해도 해당 참조형 데이터만 얕은 복사가 된다.
const fruits = ['apple', 'banana', 'cherry', ['orange']]
const shallowCopy = [...fruits]

fruits[3].push('test')
shallowCopy === fruits  // true

 

이 경우에는 lodash 라이브러리를 이용하는 것이 좋다.

const fruits = ['apple', 'banana', 'cherry', ['orange', 'test']]
const shallowCopy = _.cloneDeep(fruits)

fruits.push('test')
shallowCopy === fruits  // false

 

내보내기 종류

export default으로 내보낸 모듈의 경우, import할때 아무런 변수명으로 지정해도 상관없다.

또한, 해당 모듈은 익명으로 이름을 지정해도 정상적으로 작동한다.

# main.js
export default () => {console.log('default export')}

import defaultExport './main.js'

 

반면에 export로 내보낸 모듈의 경우, 정의한 변수명으로 import 해야한다.

모듈을 기명으로 지정해야 정상적으로 작동한다.

# main.js
export consol() => {console.log('export')}

import {consol} './main.js'

 

export default는 js 파일내에 하나만 존재한다.

 

export로 가져온 경우, 다른 이름으로 사용하도록 변경할 수도 있다.

# main.js
export consol() => {console.log('export')}

import {consol as hello} './main.js'

 

import

export된 데이터를 와일드카드를 이용하여 사용할 수 있다.

# main.js
export consol() => {console.log('export')}
export card() => {console.log('card')}

import * as wildCard './main.js'

wildCard.card()

 

JSON

AJAX 통신을 이용할때, 주고 받는 데이터 포맷이다.

 

자바스크립트의 경우에는 문자열 자료형 문법을 사용할때 작은 따옴표, 큰 따옴표, 백틱 기호를 사용할 수 있다.

 

그러나 JSON의 경우 문자열 자료형의 경우에는 큰 따옴표만 사용 가능하다.

 

json 파일은, 하나의 데이터만 정의가능하다.

여러개의 데이터를 정의하려면, 배열이나 객체데이터 안에 정의한다.

# data.json
{
"string": 'String',
"number": 123,
"boolean": true,
"null": null,
"object": {}
"array": []
}

 

json파일은 하나의 문자 데이터이다.

import data "./data.json"

console.log(typeof data)	// string

 

json파일처럼 특정 데이터를 string 타입으로 변환하려면, JSON.stringify()를 이용한다.

const data = {
    "string": 'String',
    "number": 123,
    "boolean": true,
    "null": null,
    "object": {}
    "array": []
}

console.log(typeof data)	// object

const result = JSON.stringify(data) 
console.log(typyof result)	// string

 

반대로, json파일에서 받은 데이터를 객체데이터로 변환하려면 JSON.parse()를 이용한다.

import data "./data.json"

console.log(typeof data)	// string

const result = JSON.parse(data)
console.log(data)		// object

 

storage

storage는 브라우저에 데이터 형태로 저장된다.

 

storage는 2가지 종류가 있다.

 

sessionstorage는 브라우저를 닫거나, 페이지를 이동하면 자동으로 데이터가 사라진다.

 

localstorage는 특별히 제거되지 않으면, 계속 유지된다.

 

localstorage로 데이터를 관리하는 방법

# 저장
localStorage.setItem('key', 'value')

# 저장
const tom = localStorage.getItem('key')

# 제거
localStorage.removeItem('key')

 

만약 객체데이터를 저장하고 싶다면, JSON.stringify()를 이용하여 저장하면 된다.

const user = {
    name: 'hello',
    age: 15
}
localStorage.setItem('key', JSON.stringify(user))

 

🙌 좋았던 점

localStorage 사용하여 데이터 저장...

프론트엔드로 애플리케이션을 개발하면서 가장 아쉬웠던 점은, 애플리케이션을 새로고침하거나 껐다가 다시 키면 저장되는게 없어 초기화상태로 바뀐다는 점이다.

 

그래서 데이터를 저장하는거는 백엔드밖에 없다고 생각하며 지내왔었는데, 이 강의를 듣고나서 프론트엔드도 데이터를 저장할 수 있는다는 것을 알게되었다.

 

물론 브라우저에 저장하는 데이터는 유출의 위험이 있어서 잘 사용되지 않는 방식이지만, 어쨌든 데이터를 저장하고 불러올 수 있다는 것이 좋았다.

 

얕은복사, 깊은복사

얕은 복사와 깊은복사에 대해 알고 있었지만, 참조형 데이터 안에 또다른 참조형 데이터가 있으면 깊은 복사를 해도 값이 복사되는 것이 아닌, 주소가 복사된다는 것을 처음알게되었다.

 

참조형 데이터 안의 또다른 참조형 데이터의 값을 복사하기 위해서는, lodash 라이브러리의 cloneDeep 메서드를 이용하면 이를 해결 할 수 있다는 것이다.

 

또, 나중에 알게된 사실은 객체의 경우 lodash 라이브러리 말고 또다른 방법으로 복사를 할 수 있다.

JSON.stringify로 객체를 문자열로 바꾸고, JSON.parse()로 객체 형태로 바꾸면 주소 연결이 끊어져서, 완전한 복사를 할 수있다.  

복사했습니다!