문자
String
String
전역 개체는 문자열의 생성자이다.
String - JavaScript | MDN
메소드
- indexOf()
indexOf() 메소드는 호출한 String 객체에서 주어진 값과 일치하는 첫번째 인덱스를 반환한다. 일치하는 값이 없으면 -1을 반환한다.
// String.prototype.indexOf()
const result = 'Hello world!'.indexOf('world')
console.log(result)
// 6
-
String.prototype == ‘ ‘
’ ‘ 문자 데이터의 리터럴이기 때문에 ‘ ‘ 사용만 해도 실행이 가능하다.
-
결과가 6인 이유
처음 ‘world’가 찾아진 부분이 6번째 이기 때문이다.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 … |
| — | — | — | — | — | — | — | — |
| H | e | l | l | o | | w | … |
- 찾는 값이 없을 때, -1 반환
const result = 'Hello world!'.indexOf('soha')
console.log(result)
// -1
-
매개변수
searchValue
: 찾으려는 문자열에 아무 값도 주어지지 않으면 문자열 “undefined”를 찾으려는 문자열로 사용한다.
-
반환 값
searchValue의 첫번째 등장 인덱스를 찾을 수 없으면 -1를 반환한다.
- boolean 값으로 반환받기
특정 문자가 없으면 -1이 반환된다.
indexOf(’soha’)
의 값이 -1이기에 비교값의 -1과 일치하여 true가 반환되어야 한다. 하지만, 비교 연산자 !==
를 사용하여 특정 문자가 없기 때문에 true가 아닌 false가 반환된다.
const str = 'Hello world!'
console.log(str.indexOf('soha') !== -1)
// false
- length
문자열의 길이 수를 알려준다.
const str = '0123'
console.log(str)
// 0123
console.log(str.length) // 4
console.log('01 23'.length) //5
-
slice()
문자열의 일부를 추출하면서 새로운 문자열을 반환한다. 즉, 원하는 구간의 문자열을 출력할 수 있게 한다.
slice(시작 지점, 끝 지점의 +1)
const str = 'Hello world!'
console.log(str.slice(0, 3))
// Hel
// 문자열 0번째부터 3번째 직전까지 출력
- 매개변수
beginIndex
: 추출 시작점인 0부터 시작하는 인덱스이다.
endIndex
: 0부터 시작하는 추출 종료점 인덱스로, 그 직전까지 추출한다.
-
replace()
앞에 있는 문자 데이터에서 첫번째 인수에 해당하는 문자를 찾아서 두번째 인수 내용으로 교체한다.
const str = 'Hello world!'
console.log(str.replace('world', 'SOHA'))
// Hello SOHA!
console.log(str.replace(' world!', ''))
// Hello
-
match()
특정한 일치하는 값을 찾아낸다.
const str = 'thesecon@gmail.com'
console.log(str.match(/.+(?=@)/))
// /.+(?=@)/ => 정규표현식
// ["thesecon", index: 0, input:"thesecon@gmail.com",
// groups: undefined]
console.log(str.match(/.+(?=@)/)[0])
// 해당 배열데이터의 0번째 배열 아이템을 활용하겠다는 의미
// thesecon
-
trim()
특정한 문자 데이터의 앞에서 시작하는 모든 공백 문자를 제거하고, 맨 뒤에서 연결되어져 있는 모든 공백문자를 제거한다.
const str = ' Hello world '
console.log(str.trim())
숫자
const pi = 3.14159265358979
console.log(pi)
// 3.14159265358979
const str = pi.toFixed(2)
console.log(str) // 3.14
console.log(typeof str) // string
const integer = parseInt(str)
const float = parseFloat(str)
console.log(integer) // 3
console.log(float) // 3.14
console.log(typeof integer, typeof float) // number number
메소드
- toFixed()
메소드가 호출될때, 인수로 소숫점에 몇번째 자리까지 유지할 것인지를 명시한다.
- typeof를 사용하여 데이터 타입을 확인한 결과 string이라는 결과가 나왔다.
- toFixed가 실행이 되면 문자 데이터가 반환된다!
- parseInt(), parseFloat()
자바스크립트에서 제공하는 전역함수이다.
문자 데이터를 숫자 데이터로 변환해준다.
- 전역함수: 전체 영역에서 언제든지 사용할 수 있는 함수이다.
- parseInt(): 인수로 숫자가 들어있는 문자 데이터를 넣게 되면 분석하여 숫자만 추출하여 숫자 데이터 정수로 변환한다.
- parseFloat(): 인수로 숫자가 들어있는 문자 데이터를 넣게 되면 분석하여 숫자만 추출하여 소숫점 자리의 숫자도 유지하면서 숫자 데이터로 변환한다.
Math (수학)
Math
는 수학적인 상수와 함수를 위한 속성 메소드를 가진 내장 객체이다. 함수 객체가 아니다.
Math - JavaScript | MDN
메소드
console.log('abs: ', Math.abs(-12))
// abs: 12
console.log('min: ', Math.min(2, 8))
// min: 2
console.log('max: ', Math.max(2, 8))
// max: 8
console.log('ceil: ', Math.ceil(3.14))
// ceil: 4
console.log('floor: ', Math.floor(3.14))
// floor: 3
console.log('round: ', Math.round(3.14))
// round: 3
console.log('random: ', Math.random())
// random: 0.06868616174987663
-
abs()
absolute의 약어이다.
Math.abs()
함수(메소드)는 주어진 숫자의 절대값을 반환한다.
인수에 음수값을 넣게 되면 양수값으로 반환된다.
-
min()
인수 값들 중에 가장 작은 값을 반환한다.
-
max()
인수 값들 중에 가장 큰 값을 반환한다.
-
ceil()
올림을 해주는 메소드이다.
정수단위에서 올림처리를 해주기 때문에 소숫점 값은 무시하고 무조건 올림을 한다.
ex) 5.13 → 6, 4.78 → 5
-
floor()
내림을 해주는 메소드이다.
소숫점의 값은 무시하고 정수단위에서 내림처리를 한다.
ex) 5.13 → 5, 4.78 → 4
-
round()
반올림을 해주는 메소드이다.
0~4는 내림, 5~9는 올림이다.
x) 5.13 → 5, 4.78 → 5, 4.5 → 5
-
random()
랜덤한 숫자(난수)를 반환한다.
// getRandom.js
export default function random() {
return Math.floor(Math.random() * 10)
}
- random이라는 함수 생성
- 작성한 로직을 return 키워드로 반환
- Math.floor사용하여 인수로 들어온 숫자 데이터를 내림처리
- 인수 내용은 random 메소드를 사용하여 무작위의 난수 생성
- 해당 난수에 곱하기 10을 해준 뒤 내림처리
- 결과: 0~9 사이의 숫자들을 랜덤하게 반환하는 코드
메인 페이지
메인 페이지는 크게 2개로 나눌 수 있다.
회원정보 파트와 프로젝트 파트로 나누며 회원정보 파트에는 회원가입하면서 기재한 내용들을 확인 할 수 있다. 프로젝트 파트에는 프로젝트 페이지로 이동과 모집중인 카드를 볼 수 있다.
회원정보 파트

구성
- 최상단에 본인의 포지션 표시
- 본인의 깃허브로 이동하는 버튼
- 회원가입시, 작성한 한 줄 소개
- 보유 스킬
- 참여한 프로젝트
더보기 버튼 클릭을 통해 프로젝트 페이지로 이동이 가능하다.
본인이 참여한 프로젝트의 제목을 클릭하면 해당 프로젝트의 상세 설명 페이지로 이동한다.
디자인
상단에 위치한 물결을 이미지가 아닌, html과 css 코드를 이용하여 만들었다.
직접 하나하나 만들기에는 어렵기에 wave 사이트의 힘을 빌려 제작하였다. 해당 페이지는 원하는 설정을 하면 이에 해당하는 코드를 만들어준다. 만들어준 코드를 복사하여 붙히기만 하면 끝이다.
- wave 디자인
사이트에서 만든 디자인을 복붙하면 다음과 같이 나온다.
여기에 나는 추가로 배경을 넣어주었다.
배경 이미지를 삽입하고 원하는 것으로 설정해주면 끝이다!
<div class="custom-shape-divider-bottom-1652199240">
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none">
<path d="M985.66,92.83C906.67,72,823.78,31,743.84,14.19c-82.26-17.34-168.06-16.33-250.45.39-57.84,11.73-114,31.07-172,41.86A600.21,600.21,0,0,1,0,27.35V120H1200V95.8C1132.19,118.92,1055.71,111.31,985.66,92.83Z" class="shape-fill"></path>
</svg>
</div>
.custom-shape-divider-bottom-1652199240 {
position: absolute;
bottom: 200px;
left: 0;
width: 100%;
overflow: hidden;
line-height: 0;
}
.custom-shape-divider-bottom-1652199240 svg {
position: relative;
display: block;
width: calc(100% + 1.3px);
height: 400px;
transform: rotateY(180deg);
}
.custom-shape-divider-bottom-1652199240 .shape-fill {
fill: #FFFFFF;
}
/* wave 배경 이미지 설정 */
.member-info {
margin-top: 200px;
background-image: url("../images/home_back.svg");
background-repeat: no-repeat;
background-size: cover;
}
투명도 설정
내가 만든 박스에 투명도를 넣어주고 싶다면 가장 간단한 방법은 opacity를 통해 투명도를 넣어주는 것이다.
그래서 나는 회원정보의 박스에만 투명도를 약간 주기 위해서 opacity를 사용하였다. 그런데, 배경에도 같이 투명도가 들어갔다.
- 문제점
opacity를 이용하여 박스에 투명도를 주려고 했으나 그의 부모 요소인 배경또한 같이 투명해짐.
.member-info {
margin-top: 200px;
background-image: url("../images/home_back.svg");
background-repeat: no-repeat;
background-size: cover;
} /* 얘도 같이 투명해짐 (부모요소) */
.member-info .text-body .row {
opacity: 0.9; /* 배경 + 자식요소까지 투명해짐*/
}
- 해결방법
opacity를 사용하는 것이 아닌, background-color rgba()를 사용하여 투명도를 준다. 이렇게 하면 원하는 배경만을 투명하게 할 수 있다.
.member-info .text-body .row {
background-color: rgba(255,255,255,0.9);
}
프로젝트 파트

구성
- 프로젝트 페이지로 이동하기 버튼
- 모집중 카드 슬라이드
Swiper
new Swiper(선택자, 옵션)
의 형태이다.
공지사항 등의 다양한 슬라이드 기능을 가지고 있다.
나는 카드가 자동으로 슬라이드 되게 하는 것과 방향 버튼 클릭시 해당 방향으로 슬라이드가 넘어가는 기능을 구현했다.
HTML
<!-- Swiper -->
<link rel="stylesheet" href="https://unpkg.com/swiper@8/swiper-bundle.min.css"/>
<script src="https://unpkg.com/swiper@8/swiper-bundle.min.js"></script>
--------------------------
<section class="project">
<div class="inner">
<div class="swiper">
<!-- 카드 내용 -->
<div class="card-list swiper-wrapper">
...
<a href="#" onclick="location.href='./project/project_info.html'" class="card swiper-slide">
...
</a>
</div>
<!-- 슬라이드 버튼 -->
<div class="swiper-prev">
<div class="material-icons">arrow_back</div>
</div>
<div class="swiper-next">
<div class="material-icons">arrow_forward</div>
</div>
</div>
</div>
</section>
- Swiper 적용
나는 cdn 방식으로 Swiper를 적용하였다.
- 방향 버튼 생성
앞 뒤 방향 클릭시 해당 방향으로 이동하기 위한 버튼을 만들었다.
JS
// new Swiper(선택자, 옵션)
new Swiper('.project .swiper', {
slidesPerView: 4, // 한번에 보여줄 슬라이드 개수
spaceBetween: 10, // 슬라이드 사이 여백
centeredSlides: true, // 1번 슬라이드가 가운데 보이기
loop: true,
autoplay: {
delay: 5000 // 5초 , 밀리세컨 단위
},
navigation: {
prevEl: '.project .swiper-prev',
nextEl: '.project .swiper-next'
}
});
- 선택자는
.project .swiper
이다.
- 옵션
slidesPerVeiw: 한번에 보여줄 슬라이드 개수
spaceBetween: 슬라이드 사이 여백
centerSides: 1번 슬라이드가 가운데 보이게 설정하기
loop: 반복 옵션, autopaly의 delay를 통해 시간 설정
navigation: Swiper에서 제공하는 앞 뒤로 이동할 수 있도록 하는 네비게이션 (버튼)
prevEl에는 뒤로 이동할 버튼을, nextEl에는 앞으로 이동할 버튼
마무리
저번에도 느꼈지만 home을 만들면서 더욱 느낀것은 작성해야 할 css 선택자가 늘어나는게 굉장히 비효율적이고 실수도 잘 나올 수 있게 한다는 것이다. SCSS를 알게되면 이렇게 길어지지 않아도 된다고 들었던 것같은데, 빨리 배워서 좀 더 간결하고 깔끔하게 만들고 싶다..!
생성자 함수 (prototype)
객체데이터의 구조
동일한 로직 반복해서 찍어낼 때의 단점
중괄호를 사용하는 객체데이터를 하나씩 만들때마다 메모리에 저장이 된다. 그렇게 저장된 객체데이터 내부에 하나의 함수 또한 데이터이다. 로직이 동일함에도 불구하고 우리가 만들어내는 객체데이터의 갯수만큼 함수도 메모리에 계속 할당된다.
즉, 메모리 낭비가 된다는 말이다.
이럴때 사용할 수 있는 것이 자바스크립트의 클래스이다.
클래스 이용하기
자바스크립트의 클래스는 프로그래밍 언어에서 사용하는 클래스와는 조금 다르다.
-
생성자 함수
생성하는 함수로, 하나의 객체 데이터가 생성된다.
function user(first, last) {
this.firstName = first
this.lastName = last
}
const soha = new user('Soha', 'Choe')
console.log(soha)
// user {firstName: "Soha", lastName: "Choe"}
- soha라는 변수에 user라는 함수를 실행해서 첫번째 변수 ‘Soha’, first에, 두번째 인수 ‘Choe’를 last에 인수로 전달한다.
- new라는 키워드를 통해서 user 함수를 실행하게 되었다. 이때 실행한 함수(user)를 생성자 함수라고 부른다.
-
리터럴
특정한 과정을 거치지 않고 손쉽게 해당하는 데이터를 생성하는 것이다.
soha 라는 변수에 할당 연산자를 통해서 중괄호를 열고 닫는 행위를 위의 코드(function user …
)처럼 복잡하게 처리를 해야 한다. 하지만 중괄호라는 특정 기호를 통해 손쉽게 한번에 만들어 낸다.
특정한 기호를 가지고 데이터를 만들어 내는 것을 리터럴 방식이라고 한다.
ex) 문자 데이터를 “”(따옴표)만을 가지고 만들어 내는 것, {} 사용한 객체 데이터, [] 사용한 배열 데이터 등등
- 인스턴스
function user(first, last) {
this.firstName = first
this.lastName = last
}
const soha = new user('Soha', 'Choe')
const amy = new user('Amy', 'Clarke')
const neo = new user('Neo', 'Smith')
console.log(soha)
console.log(amy)
console.log(neo)
// user {firstName: "Soha", lastName: "Choe"}
// ...
- this 라는 것은 생성자 함수(user)를 통해서 그것이 할당되어져 있는 앞의 객체 부분(soha …)의 그 내용을 지칭하는 것이다.
- new라는 키워드를 통해서 생성자 함수로 실행한 결과(’Soha’, ‘Choe’)를 반환해서 할당된 변수(soha)를 생성자 함수의 인스턴스라고 부른다.
soha, amy, neo 모두 인스턴스들이다.
- prototype
function User(first, last) {
this.firstName = first
this.lastName = last
}
User.prototype.getFullName = function () {
return `${this.firstName} ${this.lastName}`
}
const soha = new User('Soha', 'Choe')
const amy = new User('Amy', 'Clarke')
const neo = new User('Neo', 'Smith')
console.log(soha.getFullName())
console.log(amy)
console.log(neo)
// Soha Choe
// user {firstName: "Soha", lastName: "Choe"}
// firstName: "Amy"
// lastName: "Clarke"
// __proto__: Object
// getFullName: f ()
// ...
// ...
- 기존 방식은 user라는 생성자 함수가 실행될때마다 다른 내용(’Soha’, ‘Neo’ 등)이 들어올 수 있기 때문에 통일해서 관리하기는 조금 어렵다.
- getFullName은 로직(
${this.firstName} ${this.lastName}
)이 동일하기 때문에 통일화하여 메모리를 효율적으로 관리할 수 있다.
- user라는 함수에 숨어져있는 prototype 속성에 getFullName을 할당해주면 몇개의 객체를 만들던지 간에 해당 함수는 메모리에 단 한번만 만들어진다.
- console.log를 이용해 getFullName를 사용할때마다 함수가 만들어지는 것이 아닌 만들어진 함수를 참조하여 출력한다.
자바스크립트의 클래스
prototype을 사용해서 new라는 키워드와 함께 생성자 함수로 인스턴스를 만들어 내는 개념들을 자바스크립트의 클래스라고 부른다.
파스칼 케이스 == 생성자 함수
함수 이름을 파스칼 케이스로 작성한다. 이 말은 즉, 함수가 new라는 키워드와 함께 생성자로 사용되는 것이라는 걸 알 수 있다.
this
일반 (Normal) 함수 내부에서는 호출 위치에서 따라서 this를 정의한다.
화살표 (Arrow) 함수에서는 자신이 선언된 함수 범위에서 this를 정의한다.
const soha = {
name: 'Soha',
normal: fuction () {
console.log(this.name)
},
arrow: () => {
console.log(this.name)
}
}
soha.normal() // Soha
soha.arrow() // undefined
-
normal의 this
normal 부분의 함수는 normal이 호출되는 위치에서 this가 정의된다.
normal 호출되는 위치 앞 객체데이터는 soha이기 때문에 soha가 곧 this이다. 거기에서 name을 꺼내 쓰는 것이기 때문에 name: ‘Soha’가 출력되는 것이다.
-
arrow의 this
arrow는 본인이 선언된 범위에서 this를 정의한다. 하지만 해당 코드에서는 범위 외부에 함수가 보이지 않기 때문에 undefined가 출력된다.
화살표 함수로 this를 사용할때 코딩하는 환경에 따라서 this가 다양한 것을 지칭할 수 있다.
-
+ 번외: 소괄호를 사용하지 않았을 때
const amy = {
name: 'Amy',
normal: soha.normal,
// 소괄호를 사용하지 않기 때문에 호출하는 것이 아님
// soha에 있는 normal 데이터 부분을 amy의 normal에 할당
arrow: soha.arrow
}
amy.normal() // Amy
amy.arrow() // undefined
생성자 함수에서의 this 정의 1
function User(name) {
this.name = name
}
User.prototype.normal = function () {
console.log(this.name)
}
User.prototype.arrow = () => {
console.log(this.name)
}
cost soha = new User('Soha')
soha.normal() // Soha
soha.arrow() // undefined
- 일반함수 this
normal 메소드가 실행되는 호출 위치와 연결되어져 있는 객체(soha), 즉 생성자로 만들어진 soha 인스턴스에 연결된다. soha가 곧 this라는 키워드가 되는 것이고 soha의 name부분에 밖에서 들어온 ‘Soha’라는 문자 데이터가 매개변수로 받아져서 name에 할당된다.
- 화살표함수 this
화살표함수가 선언된 범위에 this를 참조하는데 영역에 함수가 따로 없기 때문에 undefined가 출력된다.
생성자 함수에서의 this 정의 2
const timer = {
name: 'Soha!!',
timeout: function () { // 일반함수
setTimeout(function () {
console.log(this.name)
}, 2000)
}
}
timer.timeout() // undefined
- this가 사용된 부분은 일반함수로 만들어져 있다.
setTimeout이라는 함수의 내부 로직으로 콜백이 들어가서 실행된다.
const timer = {
name: 'Soha!!',
timeout: function () { // 일반함수
setTimeout(() => {
console.log(this.name)
}, 2000)
}
}
timer.timeout() // Soha!!
- this가 사용된 부분을 화살표 함수로 변경했다.
화살표 함수를 감싸는 timeout함수(메소드를 정의할 때 사용한 함수)가 함수의 범위가 된다. 함수 범위는 timeout이고 timeout의 this는 곧 일반함수가 정의된 timer라는 객체데이터를 가리킨다.
즉, 여기서의 this는 timer가 된다. timer에서의 name은 Soha!!이다.
일반함수 생략화
: function을 생략해도 사용이 가능하다.
const soha = {
name: 'Soha',
normal() { // fuction 부분 생략해도 사용 가능!
console.log(this.name)
},
arrow: () => {
console.log(this.name)
}
}
soha.normal() // Soha
soha.arrow() // undefined
결론
어떤 것이 더 좋고 나쁘다는 것은 없다. 상황에 따라서 일반함수, 화살표 함수를 잘 활용하여 사용하자!
ES6 Classes
생성자 함수를 Class키워드를 통해 새롭게 갱신하기
상속 (확장)
새로운 클래스를 만들때, 이미 정의가 되어져 있는 클래스를 확장(상속)해서 굉장히 간단하게 구현을 할 수 있다.
class Vehicle {
constructor(name, wheel) {
this.name = name
this.wheel = wheel
}
}
const myVehicle = new Vehicle('운송수단', 2)
console.log(myVehicle)
// Vehicle {name: "운송수단", wheel: 2}
// name: "운송수단"
// wheel: 2
class Bicycle extends Vehicle {
constructor(name, wheel) {
super(name,wheel)
}
}
const myBicycle = new Bicycle('삼천리', 2)
const daughtersBicycle = new Bicycle('세발', 3)
console.log(myBicycle)
console.log(daughtersBicycle)
// Bicycle {name: "삼천리", wheel: 2}
// name: "삼천리"
// wheel: 2
// Bicycle {name: "세발", wheel: 3}
// name: "세발"
// wheel: 3
class Car extends Vehicle {
constructor(name, wheel, license) {
super(name, wheel)
this.license = license
}
}
const myCar = new Car('벤츠',4, true)
const daughersCar = new Car('포르쉐', 4, false)
console.log(myCar)
console.log(daughtersCar)
// Car {name: "벤츠", wheel: 4, license: ture}
// license: true
// name: "벤츠"
// wheel: 2
// Car {name: "포르쉐", wheel: 4, license: false}
// license: false
// name: "포르쉐"
// wheel: 3
- extends
확장(상속)을 의미하는 키워드이다.
extends 앞에는 새로운 클래스 명, 뒤에는 확장할 부모 클래스 명을 적는다.
- super()
super()은 extends 키워드 뒤에 붙어있는 확장된 클래스 (Vehicle)을 의미한다. super가 있는 자리에서 Vehicle이 실행된다.
- 진정한 의미의 확장
기존 클래스의 내용을 extends와 super을 통해 가져온 다음에 추가적인 내용을 작성하는 것이 진정한 확장이다.
Vehicle (운송수단)에서 Car(자동차)로 확장이다.
Git Merge(병합)
A 브랜치: 상위 브랜치, 병합 당할 브랜치
B 브랜치: 하위 브랜치, 병합 할 브랜치
A 브랜치로 이동한 후, merge를 해준다.
git switch A
git merge B
git push origin A
충돌
git merge 사용 시, 동일한 파일을 수정한 경우에 해당 파일에서 충돌이 일어난다.
- 충돌 예시
- A 브랜치
<!-- hello.html -->
<p>안녕하세요?</p>
- B 브랜치
<!-- hello.html -->
<p>안녕하세요!</p>
- 충돌
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both added: hello.html
- 파일 수정
<<<<<<< HEAD
<p>안녕하세요?</p>
=======
<p>안녕하세요!</p>
>>>>>>> develop
HEAD 아래 있는 내용은 A브랜치(병합 당할) 내용, develop 위의 내용은 B브랜치 내용이다.
두 내용 중 필요한 내용만을 남기거나 수정하면 된다.
- 커밋
메세지가 뜨면 메세지 저장후 :wq로 나오면 커밋이 된다!
![rejected] non-fast-forward error
해당 에러는 merge 에러는 아니지만 merge를 하다가 발생한 에러라서 여기에 적는다.
![rejected] non-fast-forward error: failed to push some refs to <원격 저장소 주소>
해당 에러는 원격 저장소와 로컬 저장소에 공통점이 없는 상태에서 병합을 시도할 경우 발생하는 에러라고 한다. 즉, 관련이 없는 저장소를 병합하는 것을 막아놓은 것이다.
- 해결방법 1
git pull origin <branch> --allow-unrelated-histories
해당 명령어를 통해 관련 없는 두 브랜치를 병합하도록 만들어준다. 다만, 해당 명령어는 단방향(Pull Request)이기 때문에 사용이 안될 수도 있다.
- 해결방법 2
git reset HEAD^
git --force push origin <branch>
git reset HEAD^
를 통해 직전 커밋 내용을 삭제하고 git --force push origin <branch>
를 통해 강제로 push를 해준다.
--force
를 붙힘으로 강제로 push 할 수 있다.
화살표 함수 **() ⇒ {}**
() ⇒ {} vs function () {}
화살표 함수는 일부 내용들을 생략해서 축약형으로 함수를 최소화할 수 있다.
화살표 함수 사용시 {}를 사용하게 되는데, 이때 객체 데이터를 나타내는 기호와 겹치게 된다.
() ⇒ ({ })
형태로 사용하면 객체 데이터도 사용할 수 있다!
// 일반함수
const double = function (x) {
return x * 2
}
console.log('double: ', double(7))
// 화살표 함수
const doubleArrow = (x) => {
return x * 2
}
// 화살표 함수 축약형
const doubleArrow = x => x * 2 // 14
const doubleArrow = (x,y) => x * y * 2 // {}생략 가능
const doubleArrow = x => '123' // 123
const doubleArrow = x => false // false
const doubleArrow = x => 1234 //1234
const doubleArrow = x => null //null
const doubleArrow = x => [1, 2, 3] // [1, 2, 3]
console.log('doubleArrow', doubleArrow(7))
즉시실행함수 IIFE
Immediately-Invoked Function Expression
함수를 사용하는데 한번만 사용하고 더이상 사용할 일이 없다면, 굳이 이름을 만들어서 아래에 호출할 필요가 없다. 이럴 때, 즉시실행함수를 사용한다.
const a = 7
// 일반함수
function double() {
console.log(a * 2)
}
double();
-
소괄호 이중 사용 (함수)()
// 즉시실행함수 - 소괄호 이중 사용 (함수)()
(function () {
console.log(a * 2)
})();
-
소괄호 사이에 소괄호 (함수()) => 권장
(function () {
console.log(a * 2)
}());
호이스팅 (Hoisting)
함수 선언부가 유효범위 최상단으로 끌어올려지는 현상
- 함수 표현
const a = 7
const double = function () {
console.log(a * 2)
}
double()
// 14
---------------------
double()
const double = function () {
console.log(a * 2)
}
// TypeError
함수 표현을 사용했을 때는 함수(double())
를 먼저 호출하는 것이 불가능하다.
- 함수 선언
const a = 7
double()
function double() {
console.log(a * 2)
}
// 14
우리가 만든 함수 선언부가 유효범위 최상단으로 끌어졌기에 오류 발생하지 않는다. 이것이 호이스팅이다.
-
호이스팅이 유용할 때
만든 복잡한 함수를 위에서 선언하게 되면 실행하기 전에 굉장히 많은 로직을 거쳐서 실행된다. 그렇기에 해석하기가 비교적 좋지 않다.
자바스크립트 호이스팅 현상을 사용하여 해석을 용이하게 한다.
만들어진 함수 선언부는 전체 코드 최하단에 작성한다. 실행하고자 하는 로직은 상단에 작성한다.
이렇게 하면 어떤 것이 실행되는지 해석하기가 용이하고 함수의 이름으로 기능을 유츄할 수 있다.
타이머 함수
-
setTimeout(함수, 시간)
일정 시간 후 함수 실행
시간단위는 ms. 1000ms -> 1초
setTimeout(function () {
console.log('SOHA')
}, 3000) // 3000 -> 3초
// 3초뒤 SOHA 출력
setTimeout(() => {
console.log('SOHA')
}, 3000)
// 3초뒤 SOHA 출력
-
clearTimeout()
설정된 Timeout 함수를 종료
Hello world! 클릭시 timer 종료하기
<html>
<head>
<script defer src="./main.js"></script>
</head>
<body>
<h1>Hello world!</h1>
<ul></ul>
</body>
</html>
const timer = setTimeout(function () {
console.log('SOHA')
}, 3000)
const h1El = document.querySelector('h1')
h1El.addEventListner('click', () => {
clearTimeout(timer)
})
// Hello world! 클릭 -> 3초가 지나도 아무것도 뜨지 않음
// 기존에는 3초뒤에 SOHA 출력해야 됨
-
setInterval(함수, 시간)
시간 간격마다 함수 실행
const timer = setInterval(function () {
console.log('SOHA')
}, 3000)
// 3초마다 SOHA 출력
-
clearInterval()
설정된 Interval 함수를 종료
Hello world! 클릭시 출력 종료하기
<html>
<head>
<script defer src="./main.js"></script>
</head>
<body>
<h1>Hello world!</h1>
<ul></ul>
</body>
</html>
const timer = setInterval(function () {
console.log('SOHA')
}, 3000)
const h1El = document.querySelector('h1')
h1El.addEventListner('click', () => {
clearInterval(timer)
})
// 3초마다 SOHA 출력
// Hello world! 클릭하면 출력이 종료 됨
콜백 (Callback)
함수의 인수로 사용되는 함수이다.
setTimeout(함수, 시간)
에서 인수로 함수가 사용이 되는데 이 함수를 콜백이라고 부른다.
function timeout() {
setTimeout(() => {
console.log('SOHA')
}, 3000)
}
timeout()
// 3초뒤 SOHA 출력
console.log('Done')
// Done 출력 후 SOHA 출력
SOHA 출력 후 Done 출력하기 -> 콜백
단, timeout 함수는 건들지 않는다.
function timeout(callback) {
setTimeout(() => {
console.log('SOHA')
callback()
}, 3000)
}
// 콜백 함수
// 인수로 화살표 함수 넣어줌
timeout(() => {
console.log('Done')
})
// SOHA 출력 후 Done 출력
- timeout 함수 인수로 화살표 함수를 넣어 Done 출력을 넣는다.
- timeout함수의 내부에서 해당 인수를 받아줄 매개변수로 callback을 넣어준다.
-
매개변수를 실행을 보장하고 싶은 장소에 함수 호출하듯이 넣는다.
함수 내부에서 매개변수를 부를 때 함수 호출하듯이 사용하는 이유!
timeout 함수의 인수로 사용된 것은 콜백 함수이다.
timeout 함수 내부에서 매개변수 이름은 callback으로 지어주었지만 실제로 사용할때, 해당 매개변수는 함수이기에 함수를 호출하는 것처럼 사용한다.
- 즉, timeout이라는 전체함수에 내가 실행을 보장하고 싶은 곳에서 하나의 함수를 실행할 수 있다.
활용
특정한 실행 위치를 보장해주는 방법으로 활용할 수 있다.