프론트 엔드 공부법
SASS , CSS 방법론, CSS 프레임워크
크로스 브라우징
Javascript : ES5, ES6, ESNext, DOM/Event, Ajax, node.js
프로토콜 : HTTP,
관리Tools: Git, Webpack, Babel, ESlint, npm
Framework: SPA(Vue,React), TypeScript, Lodash, Axios
TDD(Test Development): Karma/ jasmine, mocha, chai
알고리즘/자료구조
15분
https://roadmap.sh/frontend
자바스크립트에서 $의 의미
1. 제이쿼리 변수를 일반변수와 구분하기 위해서 사용함
2. 자바스크립트 내부에서 document.getElementByid의 줄임말로 사용
ejs 란?
ejs는 Embedded JavaScript의 약자로, 쉽게 말하면 자바스크립트가 내장되어 있는 html 파일입니다.
node.js 진영에서 많이 사용하는 템플릿엔진입니다. 문법이 단순합니다. ejs는 html 안에서 <% %>를 이용해서 서버의 데이터를 사용하거나 코드를 실행할 수 있습니다.
ejs는 html의 태그처럼 자바스크립트 내용을 삽입할 수 있습니다. 매우 큰 강점인데, 이것을 이용해 페이지를 동적으로 짜는 것이 수월합니다. 일반 html 파일은 무조건 "script" 태그를 이용해 분리를 시켜야하지만, ejs는 지정된 태그를 통해 스크립트 내용을 하나의 요소처럼 사용될 수 있게 합니다. 또한 서버에서 보낸 변수를 가져와 사용할 수 있습니다.
JAVASCRIPT {
● 변수
변수는 3단계 생성과정을 거친다.
선언 단계 -> 초기화 단계 -> 할당 단계)
var: 한번 선언된 변수를 다시 선언할 수 있다 , 선언하기 전에 사용할 수 있다. / var는 선언과 초기화가 동시에 된다. 그래서 할당전에 호출하면 에러가 아닌 undefined가 나온다.
let : 한번 선언된 변수를 다시 선언할 수 없다. / let은 선언과 초기화, 할당이 따로따로 된다.
const: 상수 / const는 선언과 초기화 할당이 동시에 된다.
let과 const는 TDZ(temporal Dead Zone)에 의해서 호이스팅 되지 않는다.
호이스팅:
스코프 내부 어디서든 변수 선언은 최상위에 선언된 것 처럼 행동
인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다 / 변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는것 그래서 var name; 이라고 하면 name에 undefined가 들어간다.
스코프: var : 함수 스코프 - 함수 내에서 선언된 변수만 지역변수에서 선언 할 수 있다.
let, const : 블록 스코프 - 모든 코드블록에서 선언된 변수는 코드블록 내에서만 유효하며 외부에서 불러올수 없다. (함수, if문, whie문, try/catch문 등 {} 블록안에 들어가는 것 들 )
● 자료형
1. null = 존재하지 않는 값
2. undefined = 값이 할당되지 않음 (즉 변수는 선언 했지만 변수에 값을 넣지않음)
3. typeof = 무슨 자료형인지 알기위해 [사용법: console.log(typeof 변수)]
alert = 확인 버튼만 있는 창
confirm = 확인 취소 버튼 있는 창
prompt = 사용자에게 입력 값을 받음
- alert, confirm, prompt도 함수임
● 함수
함수 사용법
// 이름(매개변수에 들어갈 값);
function 이름 (매개변수) {
내용
}
예제 1
function sayHello(name) {
const msg = `Hello, ${name}`;
console.log(msg);
}
sayHello('Mike');
함수의 사용이유 및 특징
1.유지보수 쉬움
2. 똑같은 함수를 여러번 사용할때 유용함
3. 함수는 한번에 한 작업만 사용하는게 좋다. (여러작업을 하게되면 함수를 잘게 쪼개서 만들어줘야 한다.)
4. 변수와 함수는 이름을 짓는게 굉장히 중요하다 ( 읽기 쉽고 어떤 동작인지 알 수 있게 이름을 지어야 한다)
예: showError // 에러를 보여줌 ,
getName // 이름을 얻어옴,
createUserData // 유저데이터 생성 ,
checkLogin // 로그인 여부 체크
전역변수 = 어디서든 접근 가능함
지역변수 = 특정 지역에서만 접근 가능함 (지역변수를 사용하는 것이 좋음)
예시 : 함수 , 객체 등 안에 변수를 선언하면 지역변수 그 바깥에 선언하면 전역변수
함수에 값을 반환하는 방법 = return 사용하기
예제 1
function add(name1, name2) {
return name1 + name2
console.log("이 코드는 절때 실행되지 않습니다");
};
const result = add(1,2);
console.log(result) //3
console.log(add(1,2)); //3
return 밑에 사용하는 모든 문장은 절때 실행되지 않음.1
● 함수 선언문 VS 함수 표현식
1. 함수 선언문
function sayHello(){
console.log("Hello");
}
sayHello();
2. 함수 표현식
let sayHello = function() {
console.log("Hello");
}
sayHello();
둘의 차이점: 호출 할 수 있는 곳의 차이가 있다.
함수 선언문은 어디서든 호출 가능함
하지만 함수 표현식은 함수 바로 밑에서만 호출 가능함
- 둘중 편한거 쓰면 됨
● 화살표 함수
let sayHello = () => {
console.log("Hello");
}
Object (객체)
객체 만드는 법
const superman = {
name : "clark",
age : 33,
키 : 값 이라고 함 (property)
}
property 란?
기본적으로 property는 어떤 값을 나타내며, 이 값이 다른 값과 연관되어 있을 때 property 라고 부릅니다.
name : 여기 안에 있는 값을 property 라고 함
객체에 접근 , 추가 , 삭제 하는방법
접근
superman.name
console.log(superman.name); // clark 찍힘
추가
superman.gender = "male"
console.log(superman.gender); // male 찍힘
삭제
delete superman.gender
console.log(superman.gender); // undefined 나옴
● for ... in 반복문
for(let key in superman) {
console.log(key) // name 과 age이 나옴
console.log(superman[key]) // clark와 33이 나옴
}
○ 함수안에 객체로 만들어보기 + for .. in 반복문 예제
예제 1
function makeObject (name , age ) {
return {
name: name, // 축약가능(name만 써도 됨)
age : age, // 축약가능(age만 써도 됨)
hobby : 'football'
}
}
const Mike = makeObject("mike", 33);
console.log(Mike); // {name: 'mike', age: 33, hobby: 'football'}
console.log('age' in Mike) //true
console.log('birthday' in Mike) // false
예제 2
function isAdult(user) {
if(!("age" in user) || user.age < 20) {
return false;
}
return true;
}
const Mike = {
name: 'mike',
age : 33
}
const jso = {
name: 'mike'
}
console.log(isAdult(Mike)) // true
console.log(isAdult(jso)) // false
for .. in 문 예제
const Mike = {
name: "Mike",
age : 30
};
for (x in Mike) {
console.log(Mike[x]) // Mike 30 나옴
}
Tip: 만약 존재하지 않는 property에 접근하면 undefined가 나온다 이때 'birthDay in superman (in 연산자)를 사용하면 property가 있는지 알 수 있다. 언제 사용하는가? 어떤 값이 넘어오는지 확신 할 수 없을때 혹은 API에서 값을 불러올때 사용한다.
● method란? (객체 안에 함수)
객체 property로 할당 된 함수를 말 한다. ( 객체 안에 함수를 사용하면 메서드라고 함)
메소드 생성하는 방법
const superman = {
name: "clark",
age : 33,
fly : function () { // : function 생략가능
console.log("날아올라 ~~")
console.log(`날아간다 ${this.name}`)
}
};
console.log(superman.fly); // 날아올라 ~~ , clark
Tip: 화살표 함수는 일반 함수와 달리 자신만의 this를 가지지 않음 화살표 내부에서 this를 사용하면, 그 this는 외부에서 값을 가져옴 그리고 그 외부에서 값을 가져오는 것이 브라우저 환경에서는 window를 node.js 환경에서는 global 을 가져온다. / this 강의보기.
● 배열 (array) : 순서가 있는 리스트
생성
let student = ['철수', '영희', ...'영수']
console.log(student[1]); // 영희
student.length : 배열의 길이를 반환해줌 (문자열의 길이도 반환해줌)
student.push(): 배열 끝에 추가해줌
student.pop(): 배열 끝 요소 제거해줌
student.shift(): 배열 앞에 추가해줌
student.unshift(): 배열 앞에 제거해줌
● 반복문 : for .. of : 단점 인덱스가 안나옴
let days = ['월', '화', '수', '목'];
for (let day of days) {
console.log(day) // 월 화 수 목 나옴
}
● 객체의 리터럴
let user = {
name: 'mike',
age: 30,
}
● 생성자 함수
사용이유 : 위의 객체 리터럴 처럼 객체를 여러개 만들어야 하는 상황이 생길때 사용한다. / 생성자 함수는 첫 글자는 무조건 대문자로 만들어주며, new 연산자를 사용해서 호출해준다..
function Item(titel, price){
// this = {} - 자동으로 생성됨
this.titel = titel;
this.price = price;
this.showPrice = function() {
console.log(`가격은 ${price}원 입니다.`);
}
// return this; - 자동으로 생성됨
}
const item1 = new Item('인형' , 3000);
const item2 = new Item('꼬꾸' , 3500);
const item3 = new Item('깨끼' , 4000);
console.log(item1, item2, item3); // '인형' , 3000 , '꼬꾸' , 3500 , 깨끼' , 4000
● computed property: 계산된 프로퍼티 라는 의미로 객체 안에 대괄호로 묶인 곳에 변수 a가 들어가게 된다. / 어떤 값이 키가될지 모를때 사용하면 유용함
예제 1
let n = "name";
let a = "age";
const user = {
[n] : 'mike',
[a] : 20
};
console.log(user); // {name: 'mike', age: 20}
예제 2
const user = {
[1 + 4]: 3,
["안녕"+ 3 + "하시오"] : "Hello" + 3
}
console.log(user); // 5: 3, 안녕3하시오: 'Hello3'
예제 3
function makeObject(key, value) {
return {
[key] : value
}
}
const obj = makeObject("나이", 33);
console.log(obj); // {나이: 33}
● 객체에서 사용 가능 한 메서드
1. Object.assign({초기값}, 객체가 들어오면 병함 됨) : 객체 복제하는 용도
예제 1
const user = {
name : "ahah",
age : 200,
}
const user2 = Object.assign({}, user);
user2.name = "dodo";
console.log(user2); // {name: 'dodo', age: 200}
console.log(user); // {name: 'ahah', age: 200}
예제 2 : 초기값에 값을 넣게되면
const user = {
name : "ahah",
age : 200,
}
const user2 = Object.assign({gender: 'male'}, user);
user2.name = "dodo";
console.log(user2); // {gender: 'male', name: 'dodo', age: 200}
console.log(user); // {name: 'ahah', age: 200}
예제 3 : 여러개 넣으면
const user = {
age : 200,
}
const user1 = {
will : "상태값"
}
const user3 = {
name: "아아"
}
const user4 = Object.assign(user, user1, user3);
console.log(user4); // {age: 200, will: '상태값', name: '아아'}
2. Object.keys(): 객체 property의 키를 배열로 반환
예제
const user = {
name : "nana",
age : 20,
gender: "man"
}
const use = Object.keys(user);
console.log(use); // ['name', 'age', 'gender']
3. Object.values(): 객체 property의 값을 배열로 반환
예제
const user = {
name : "nana",
age : 20,
gender: "man"
}
const use = Object.values(user);
console.log(use); // ['nana', 20, 'man']
4. Object.entries(): 객체 property의 키와값을 배열로 반환
예제
const user = {
name : "nana",
age : 20,
gender: "man"
}
const use = Object.entries(user);
console.log(use);
// [Array(2), Array(2), Array(2)]
// 0: (2) ['name', 'nana']
// 1: (2) ['age', 20]
// 2: (2) ['gender', 'man']
5. Object.fromEntries(): 배열 property의 키와값을 객체로 반환
예제 1
const user = [
["name", "nana"],
["age", 20],
["gender" , "man"]
]
const use = Object.fromEntries(user);
console.log(use);
// {name: 'nana', age: 20, gender: 'man'}
// age: 20
// gender: "man"
// name: "nana"
● 심볼(Symbol)
객체의 property key 는 문자형과 symbol형 두가지로 만들수 있다
심볼은 유일한 식별자를 만들때 사용한다. (유일성이 보장됨으로 전체 코드중에 딱 하나가 된다) , 심볼은 이름이 같더라도 모두 다른 존재인다.
생성
const a = Symbol('설명을 넣어주세요');
console.log(a); // Symbol(설명을 넣어주세요)
예제 1 : property key 가져오는 방법
const obj = {
1: '1 입니다.',
false: '거짓 입니다.'
}
console.log(obj); // {1: '1 입니다.', false: '거짓 입니다.'}
console.log(obj[1]); // 1 입니다.
console.log(obj[false]); // 거짓 입니다.
Symbol.for(): 전역 심볼
가끔 전역변수 처럼 이름이 같으면 같은 객체를 가르켜야 할 때가 있는데 심볼도 그렇게 사용하기 위해서 Symbol.for 이란걸 사용한다
● 수학 메소드
1. toString() : 10진수를 2진수 또는 16진수로 변경해준다.
예제 1
let num = 10;
console.log(num.toString()); // 10
console.log(num.toString(2)); // 1010
console.log(num.toString(16)); // a
2. Math.PI() : 원주율을 구해준다.
console.log(Math.PI); // 3.141592653589793
Math.ceil() : 올림
예제 1
let num = 11.1;
console.log(Math.ceil(num)); // 12
3. Math.floor() : 내림
예제 1
let num = 11.5;
console.log(Math.ceil(num)); // 11
4. Math.rount() : 반올림
5. toFixed() : 소수점 자리수에 맞춰서 구해준다.
예제 1
let num = 11.1123;
console.log(num.toFixed(6)); // 11.112300
6. isNaN() : NaN인지 아닌지 알려준다.
7. parseInt() : 문자를 숫자로 바꿔준다.
8. parseFloat() : 문자를 부동소수점으로 바꿔준다.
10. Math.random() : 랜덤 숫자를 반환해준다.
11. Math.max() : 최댓값을 구해준다.
12. Math.min() : 최솟값을 구해준다.
13. Math.abs() : 절대값을 구해준다.
14. Math.pow(n, m) : 제곱을 구해준다.
15. Math.sqrt() : 제곱근을 구해준다.
백틱 (` `) : 백틱 안에는 ${} 이용해 안에 변수를 선언 할 수 있다.
백틱은 여러줄을 이용 할 수 있다.
예제 1
let num = `오늘은 맑고
흐리고
샛물이
좋다
console.log(num);
문자도 대괄호를 이용하면 특정위치에 접근 가능하다.
예제 2
let num = `오늘은 맑고
흐리고
샛물이
좋다
`
console.log(num[2]); // 은
16. indexOf() : 문자를 인수로 받아 몇번째 위치하는지 알려준다.
17. slice(n, m) : n부터 m까지의 문자열을 반환해준다 단, m에 적은 숫자 -1 까지 반환해주며 m에 숫자를 적지 않으면 문자열 끝까지 반환해준다.
18. substring(n, m) : n과 m 사이의 문자열을 반환한다.
19. substr(n,m) : n부터 시작해서 m개를 가져오는 형태이다.
20. trim() : 은 앞과 뒤 공백을 제거해준다.
21. repeat() : 문자열을 여러번 반복한다.
● 배열 메소드
22. arr.splice(n, m, x) : 배열의 특정 요소를 지우고 지운 자리에 새로운
값을 추가 할 수 있다.
n: 시작 , m: 끝 , x: 추가 할 숫자
예제 1
let arr = [1,2,3,4,5];
arr.splice(1,2);
console.log(arr); // [1,4,5] 2와 3이 지워짐
예제 2 : x에 값을 넣어서 추가함
let arr = [1,2,3,4,5];
arr.splice(1, 3, 100, 200);
console.log(arr); // [1, 100, 200, 5]
예제 3 : 끝 값에 0을 넣으면 아무것도 지우지 않고 추가 가능
let arr = ["1,2,3,4,5", "입니다", "추가해주세요" ];
arr.splice(1, 0, "대한민국");
console.log(arr); // ['1,2,3,4,5', '대한민국', '입니다', '추가해주세요']
예제 4 : 삭제된 요소를 다른 변수에 저장 할 수 있다.
let arr = [1,2,3,4,5 ];
const result = arr.splice(1, 2,);
console.log(arr); // [1, 4, 5]
console.log(result); // [2, 3] 삭제된 요소가 들어감
arr.concat : 인자로 주어진 배열이나 값들을 합쳐서 새배열을 반환한다.
예제 5
let arr = [1, 2];
arr.concat([3,4,5,6]);
console.log(arr); // [1, 2, 3, 4, 5, 6];
arr.forEach(fn) : (for / for.. of 외) 배열을 반복한다
forEach(해당 인수, 인덱스 번호, 해당 배열 자체) 보통 첫번째와 두번째만 사용한다.
예제 6
let arr = ["Mike", "Tom", "Jane"];
arr.forEach((value, Mike) => {
console.log(`${Mike + 1}. ${value}`);
});
//1. Mike
// 2. Tom
// 3. Jane
23. arr.indexOf() : 해당열의 index를 반환하고 없으면 -1을 반환한다
예제 1
let arr = [1, 2, 3, 4, 5, 6, 1, 2, 3];
console.log(arr.indexOf(3)); // 2
예제 2 : 두번째 인수는 시작위치를 말한다. ? 아닌거 같음
let arr = [1, 2, 3, 4, 5, 6];
console.log(arr.indexOf(4, 2)); // 3 나옴
24. arr.lastInedxOf : 끝에서부터 탐색하고 싶으면 사용
25. arr.includes() : 배열내에 원하는 값이 있으면 true 그렇지 않으면 false 를 반환한다.
let arr = [1, 2, 3, 4, 5, 6 , "야"];
console.log(arr.includes("야")); // true
26. arr.find(fn) : 인자에 함수를 넣어서 찾을수 있으며 첫번째 true 값만 반환하고 끝난다 만약 없으면 undefined를 반환한다.
예제 1
let arr = [1, 2, 3, 4, 5, 6];
const result = arr.find((num) => {
return num % 2 == 0;
});
console.log(result); // 2
arr.findIndex(fn) : 조건에 만족하는 Index를 찾아낸다
예제 2
let arr = [1, 2, 3, 4, 5, 6];
const result = arr.find((num) => {
return num % 2 == 0;
});
console.log(result); // 1 (인덱스 번호 찾아옴)
27. arr.filter(fn) : 조건에 만족하는 모든 요소를 배열로 반환하고 싶을때는 filter를 이용한다
예제 1
let arr = [1, 2, 3, 4, 5, 6];
const result = arr.filter((num) => {
return num % 2 == 0;
});
console.log(result); // [2, 4, 6]
28. arr.reverse() : 배열을 역순으로 재정렬 해준다.
29. arr.map(fn) : 함수를 받아 특정 기능을 시행하고 새로운 배열을 반환한다.
예제 1 : map 사용법 (객체와 인덱스를 받아야 한다)
let userList = [
{name: "mike" , age: 30},
{name: "jane" , age: 20},
{name: "Tome" , age: 15},
];
let newuserLinst = userList.map((user, index) => {
return Object.assign({} , user, {
id: index + 1 ,
isAdult: user.age > 19,
});
});
console.log(newuserLinst);
// 0: {name: 'mike', age: 30, id: 1, isAdult: true}
// 1: {name: 'jane', age: 20, id: 2, isAdult: true}
// 2: {name: 'Tome', age: 15, id: 3, isAdult: false}
30. arr.join() : 배열을 합쳐서 문자열을 만들고 싶을때 사용
31. arr.split() : 문자를 나눠서 배열을 만들어준다.
예제 1
let str = "Hello, My, name, is, Mike";
console.log(str.split(",")); // ['Hello, My, name, is, Mike']
32. Array.isArray() : 배열인지 알려준다.
예제 1
let user = {
name: "mike",
age : 30
}
let users = ["mike" , "30"];
console.log(Array.isArray(user)); // false
console.log(Array.isArray(users)); // true
33. arr.sort() : 배열을 재정렬 해준다
예제 1
let arr = [1,4,3,2,6,5];
arr.sort();
console.log(arr); // [1, 2, 3, 4, 5, 6]
예제 2 : sort는 복잡한 값은 제대로 처리를 못 하기 때문에 인수로 정렬 로직을 담은 함수를 만들어줘야 한다.
바꾸기 전
let arr = [27, 8, 5, 13];
arr.sort();
console.log(arr); // [13, 27, 5, 8]
바꾼 후 방법 1
let arr = [27, 8, 5, 13];
function fn (a, b) {
return a - b;
}
arr.sort(fn);
console.log(arr); // [5, 8, 13, 27]
바꾼 후 방법 2
let arr = [27, 8, 5, 13];
arr.sort((a,b) => {
return a - b;
});
console.log(arr); // [5, 8, 13, 27]
34. arr.reduce(fn) : 배열을 돌면서 원하는 작업을 하고 최종 값을 반환한다.
(첫번째 값 : 현재까지(누적) 계산된 값 , 두번째 값: 현재 값 , 세번째 값: 초기 값)
예제 1
let arr = [1, 2, 3, 4, 5];
let result = arr.reduce((oldnum , renum) => {
return oldnum + renum;
}, 0)
console.log(result); // 15
예제 2 : 성인들만 뽑아오는 기능
let userList = [
{name: "mike" , age : 25},
{name: "jane" , age : 32},
{name: "alex" , age : 21},
{name: "alse" , age : 40},
{name: "odld" , age : 10},
];
let result = userList.reduce((prev, cur) =>{
if(cur.age > 19) {
prev.push(cur.name);
}
return prev;
}, []);
console.log(result); // ['mike', 'jane', 'alex', 'alse']
● 구조분해할당(Destructuring assignment)
구조 분해 할당 구문은 배열이나 객체의 속성을 분해해서 그 값을 변수에 담을수 있게 하는 표현식이다.
배열의 구조분해 할당
예제 1 : 사용법
let [x, y] = [1, 2];
console.log(x, y); // 1 2
예제 2
let users = ['Mike', 'Tome', 'Jane'];
let [user1, user2, user3] = users;
consoel.log(user1); // Mike
consoel.log(user2); // Tom
consoel.log(user3); // Jane
예제 3 : 값을 지정하지 않으면 undefined가 나오기 때문에 기본 값을 설정해 주자!
let [a,b,c] = [1,2];
console.log(a, b, c); // 1 2 undefined
let [a,b,c = 1] = [1,2]; // 1 2 1 이 나온다.
예제 4 : 값 무시하기
let [a, ,c] = [1,2,3];
console.log(a, c); // 1 3
● 객체 구조 분해
예제 1 : 사용법
let user = {name: "Mike", age: 30};
let {name, age} = user;
console.log(name); // Mike
console.log(age); // 30
예제 2 : 객체 property 이름 변경하기
let user = {name: "Mike", age: 30};
let {name: userName, age: userAge} = user;
console.log(userName); // Mike
console.log(userAge); // 30
● 나머지 매개변수(Rest parameters) : ... 점 3개를 사용한다.
함수에 인수를 얹는 방법은 2가지가 있고 한가지는 arguments(아규먼츠)로 접근하는 방법 혹은 나머지 매개변수( ...) 를 사용하는 것이다 그리고 화살표 함수에는 arguments가 없다 ( 가급적 ES6 문법 이상을 사용하면 나머지 매개변수를 사용하는게 좋다)
나머지 매개변수는 정해지지 않은 갯수의 인수를 배열로 나타낼수 있게 한다. / 배열의 메서드도 사용 가능하다.
예제 1 : 사용법
function showName(...names) {
console.log(names);
}
showName(); // []
showName(1234); // [1234]
showName("Mike" , "Tom"); // ['Mike', 'Tom']
예제 2 : 활용하기
function add(...numbers) {
let result = 0;
numbers.forEach((num)=> (result += num));
console.log(result);
}
add(1, 2, 3); // 6
add(1, 2, 3, 4, 5, 6, 7, 8); // 36
예제 3 : 활용하기 상급
function User(name, age, ...skils) {
this.name = name;
this.age = age;
this.skils = skils;
}
const user1 = new User("Mike", 18 , 'html', 'Css');
const user2 = new User("mage", 18 , 'java', 'framework');
console.log(user1);
// User {name: 'Mike', age: 18, skils: Array(2)}
// age: 18
// name: "Mike"
// skils: (2) ['html', 'Css']
console.log(user2);
// User {name: 'mage', age: 18, skils: Array(2)}
// age: 18
// name: "mage"
// skils: (2) ['java', 'framework']
arguments 란?
함수로 넘어온 모든 인수에 접근 할 수 있으며, 함수 내에서 이용가능한 지역변수이다. array 형태의 객체이다. length와 index 속성은 가지고 있지만 배열의 내장 메서드는 사용 할 수 가 없다.
예제 1 : 사용법
function showName(nmae) {
console.log(arguments.length); // 2
console.log(arguments[0]); // Mike
console.log(arguments[1]); // TOM
}
showName("Mike" , "Tom");
● 전개 구문 (Spread syntax) 스프레드 연산자
[배열]
사용이유: 배열의 값들을 중간에 빼고 넣고 하는 작업들은 배열 메소드(push,splice, concat 등)를 사용해야 해서 굉장히 번거로운데 전개구문을 사용하면 굉장히 편리하다 (예제 2)
예제 1
let arr1 = [1,2,3];
let arr2 = [4,5,6];
let result = [arr1, arr2];
console.log(result);
// 0: (3) [1, 2, 3]
// 1: (3) [4, 5, 6]
let arr1 = [1,2,3];
let arr2 = [4,5,6];
let result = [...arr1, ...arr2];
console.log(result); // [1, 2, 3, 4, 5, 6]
예제 2
let arr1 = [1,2,3];
let arr2 = [4,5,6];
let result = [0, ...arr1, ...arr2, 7 , 8];
console.log(result); // [0, 1, 2, 3, 4, 5, 6, 7, 8]
● 전개 구문(Spread syntax) 스프레드 연산자
[객체]
사용이유: Object.assign을 사용하지 않아도 복제가 된다.
let arr1 = {name: "Kie" , age: 20};
let result = {...arr1};
result.name = "TOM"
console.log(result); // {name: 'TOM', age: 20}
● 클로저 (Closure) : 함수가 생성된 이후에도 상위 함수의 매개변수에 접근 가능한 것 / 함수와 렉시컬 환경의 조합 이며, 함수가 생성될 당시의 외부 변수를 기억하고 생성 이후에도 계속 접근이 가능한 것을 말 한다.
Tip: 자바스크립트는 어휘적 환경(Lexical)을 같는다.
예제 1
// 1. 코드가 실행이 되면 스크립트에서 선언한 변수&함수들이 (전역)Lexical(one, addOne: function) 환경에 올라간다
// let에 들어있는 one 은 초기화가 안되 있는 상태로 error가 난다 - 사용 불가능
// 하지만 함수선언문은 변수와 달리 바로 초기화가 된다. 사용가능 단, 변수에 할당한 함수표현식은 불가능
let one; // 2. one 이 초기화가 되고 값은 들어있지 않아서 undefined가 나온다 - 사용가능
one = 1; // 3. one에 숫자가 할당이 된다. Lexical 환경에 one : 1 이라고 변경이 된다.
function addOne(num) {
conosole.log(one + num);
}
addOne(5); // 4. 함수가 실행되고 그 순간 새로운 (내부)Lexical 환경이 만들어지고
// (매개변수와 지역변수들이 저장된다) num : 5 라는 값이 올라간다.
// 내부 Lexical 환경은 전역 Lexical환경의 참조를 받는다.
// 코드에서 변수를 찾을때 내부 -> 외부 -> 전역 순으로 찾게된다.
예제 2
function makeAdder(x) {
return function (y) {
return x + y;
}
}
const add3 = makeAdder(3);
// 2. add3 이 실행 될때 makeAdder Lexical 환경이 만들어지고 X:3 이 올라간다
console.log(add3(2));
// 3. function (y) 가 실행이 되고 이때 익명함수 Lexical 환경이 만들어지고 y: 2 가 올라간다.
// 1. 전역 Lexical 환경에 makeAdder: function과 add3: 초기화x 가 들어간다.
예제 3 : 실제 예제
function makeCounter() {
let num = 0;
return function() {
return num ++;
}
}
let counter = makeCounter();
console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2
setTimeOut(함수, 시간, 인수): 일정 시간이 지난 후 함수를 실행
clearTimeout(): setTimeOut 을 중간에 취소시켜 준다.
setInterval(함수, 시간, 인수): 일정 시간 간격으로 함수를 반복한다.
clearInterval(): setInterval을 중간에 취소시켜 준다.
call, apply, bind 메서드 : 함수 호출 방식과 관계없이 this 를 지정할 수 있다.
call 예제 1 : call 은 매개변수를 직접 받는다
const ame = {
name : "Mike"
}
function showThisName() {
console.log(this.name);
}
showThisName.call(ame); // Mike
call 예제 2
const ame = {
name : "Mike"
}
function update(birs, occ) {
this.birs = birs;
this.occ = occ;
}
update.call(ame, 1999, 'poth')
console.log(ame); // {name: 'Mike', birs: 1999, occ: 'poth'}
apply 예제 1 : 매개변수를 배열로 받는다.
const ame = {
name : "make"
}
function update(birs, occ) {
this.birs = birs;
this.occ = occ;
}
update.apply(ame, [1999, "poth"])
console.log(ame); // {name: 'Mike', birs: 1999, occ: 'poth'}
bind 예제1 : bind를 사용하면 함수의 this 값을 영구히 바꿀수 있다.
Tip: 객체에는 자신의 property를 가지고 있는지 확인하는 메소드가 있다 = hasOwnProperty
● 상속 : 부모의 데이터를 상속 받는다.
prototype : 을 사용하는 이유는 중복을 줄이고 상속시키기 위해서이다. / instanceof를 이용해서 객체와 생성자를 판단한다. (true면 생성자이다.) / instance를 생성자라고 한다.
예제 1
const car = {
wheels: 4,
option: "PaPA"
}
const bmw = {
color: "red",
navigation: 1,
dirver() {
console.log("운전중입니다.");
}
}
const audi = {
color: "blue",
wheels: 4,
cow: 1,
sports() {
console.log("스포츠 모드.");
}
}
const benz = {
color: "white",
wheels: 4,
sese() {
console.log("안전모드.");
}
}
bmw.__car__ = car;
audi.__car__ = car;
benz.__car__ = car;
검색은 bmw.__car__.option
예제 2 : 간편한 방법
const Bmw = function (color) {
this.color = color;
}
Bmw.prototype.wheels = 4;
Bmw.prototype.dirver = function() {
console.log("drive..");
};
● Class (클래스) : 클래스는 new 없이 생성 할 수 없지만 생성자 함수는 가능하다 (단, undefined가 뜸)
예제 1
// 클래스
class User2 {
constructor(name, age) {
this.name = name;
this.age = age;
}
showName() {
console.log(this.name);
}
}
const tom = new User2("Tom", 15);
console.log(tom); // User2 {name: 'Tom', age: 15 , Prototype{function}}
console.log(tom.showName()); // Tom
// 생성자 함수
const User = function (name, age) {
this.name = name;
this.age = age;
this.showName = function () {
console.log(this.name);
};
};
const mike = new User("Mike" , 30);
const make = new User("mm" , 20);
console.log(mike); // User {name: 'mike', age: 30, showName: ƒ}
console.log(make); // User {name: 'make', age: 20, showName: ƒ}
클래스에서 상속은 extends를 사용한다.
예제 1
class Car {
constructor(color) {
this.color = color;
this.wheels = 4;
this.name = "Audi";
}
drive() {
console.log("power");
}
stop() {
console.log("break");
}
}
class Bmw extends Car {
park() {
console.log("parking");
}
}
const Z4 = new Bmw("blue");
예제 1 : 클래스 메소드 오버라이딩 & 클래스 생성자 오버라이딩
class Car {
constructor(color) {
this.color = color;
this.wheels = 4;
this.name = "Audi";
}
drive() {
console.log("power");
}
stop() {
console.log("break");
}
}
class Bmw extends Car {
constructor(color) {
super(color); // 생성자 오버라이딩 ( 항상 부모 클래스의 constructor을 생성해줘야 한다.)
this.navigation = 1;
}
park() {
console.log("parking");
}
stop() {
super.stop(); // 메소드 오버라이딩 (super.메소드명 을 사용 - 오버라이딩)
console.log("OFF");
}
}
const Z4 = new Bmw("blue");
● promise( 프로미스 ) : 상품이 준비되는 동안 다른 작업을 하기 위해서 사용하는 것이 프로미스 이다
사용법 예제
// new Promise가 반환하는 Promise 객체는 state: pending(대기)와 result: undefined를 property로 반환 받는다.
// state가 pending 이였다가 resolve를 반환 받으면 state: fulfilled(이행됨) , result: value 가 반환된다.
// state가 pending 이였다가 reject를 반환 받으면 state: rejected(거부됨) , result: error가 반환된다.
// 판매자
const promise = new Promise ((resolve, reject) => {
// resolve : 성공 했을때 실행되는 함수
// reject: 실패 했을때 실행되는 함수
// 어떤 일이 완료되었을때 실행되는 함수를 콜백함수라고 한다.
setTimeout(()=>{
resolve('ok')
// reject(new Error('error..'))
}, 3000)
});
// 소비자
promise.then(
function(result) {
console.log(result + "가지러 가자");
}, // Promise가 이행 되었을때 실행된다. / resolve의 ok라는 값이 들어온다
function(err) {
console.log("다시 주문해주세요");
} // Promise가 거부 되었을때 실행된다. // reject의 error라는 값이 들어온다.
)
then 이외에 사용 할 수 있는 것으로는 catch와 finally가 있고 catch는 reject인 경우에 실행이 된다.
finally는 이행이든 거부든 처리가 완료되면 항상 실행된다.
catch와 finally를 사용한 예제 : catch문을 사용하는 것 이 좋다.
promise.then(
function(result) {
console.log(result + "가지러 가자");
}
).catch (
function(err) {
console.log("다시 주문해주세요");
}
).finally (
function() {
console.log("주문 끝");
}
)
예제 2 : 실제 실행시 ( resolve 버전 )
const pr = new Promise ((resolve, reject) => {
setTimeout(() => {
resolve("완성 되었습니다.");
// reject("재료가 모두 소진 되었습니다.");
}, 2000);
})
console.log("고객님 주문 해주세요");
pr.then((result)=>{
console.log(result);
})
.catch((err)=>{
console.log("재료가 모두 소진 되었습니다.");
})
.finally(()=>{
console.log("다음에 또 와주세요.");
})
// 고객님 주문 해주세요
// 완성 되었습니다.
// 다음에 또 와주세요.
예제 3 : 실제 실행 시 ( reject 버전 )
const pr = new Promise ((resolve, reject) => {
setTimeout(() => {
// resolve("완성 되었습니다.");
reject("재료가 모두 소진 되었습니다.");
}, 2000);
})
console.log("고객님 주문 해주세요");
pr.then((result)=>{
console.log(result);
})
.catch((err)=>{
console.log(err);
})
.finally(()=>{
console.log("다음에 또 와주세요.");
})
// 고객님 주문 해주세요
// 재료가 모두 소진 되었습니다.
// 다음에 또 와주세요.
예제 4 : 콜백 지옥을 만들어보자.
const liceburger = (callback) => {
setTimeout(function() {
console.log("라이스버거 완성");
callback();
}, 1000);
};
const bulgogiburger = (callback) => {
setTimeout(function() {
console.log("불고기버거 완성");
callback();
}, 3000);
};
const tomatobuger = (callback) => {
setTimeout(function() {
console.log("토마토버거 완성");
callback();
}, 2000);
};
liceburger(function(){
bulgogiburger(function(){
tomatobuger(function(){
console.log("모든 음식이 완성 되었습니다.")
})
})
})
// 라이스버거 완성
// 불고기버거 완성
// 토마토버거 완성
// 모든 음식이 완성 되었습니다.
예제 5 : 콜백 지옥을 만든 콜백함수를 사용하지 않고 Promise로 사용해 보자! // promise 체이닝
const liceburger = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res("라이스버거 완성");
}, 1000);
});
};
const bulgogiburger = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("불고기버거 완성");
}, 3000);
});
};
const tomatobuger = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("토마토버거 완성");
}, 2000);
});
};
liceburger()
.then(res => bulgogiburger(res))
.then(res => tomatobuger(res))
.then(res => console.log(res))
.catch(() => {console.log("현재 주문하신 음식의 재료가 소진되었습니다.")})
.finally(() => {console.log("모든 음식이 완성 되었습니다.")})
// 라이스버거 완성
// 불고기버거 완성
// 토마토버거 완성
// 모든 음식이 완성 되었습니다.
Promise all : 1번 1초/ 2번 3초/ 3번 2초가 걸림으로 총 6초가 걸리게 된다 이 시간을 3초로 바꾸기 위해서 Promise all 을 사용한다
const liceburger = () => {
return new Promise((res, rej) => {
setTimeout(() => {
rej("라이스버거 완성");
}, 1000);
});
};
const bulgogiburger = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("불고기버거 완성");
}, 3000);
});
};
const tomatobuger = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("토마토버거 완성");
}, 2000);
});
};
console.log("시작")
Promise.all([liceburger(), bulgogiburger(), tomatobuger()])
.then((res)=>{console.log(res)});
// 시작
// ["라이스버거 완성", "불고기버거 완성", "토마토버거 완성"]
● Async & Await : async&await을 사용하면 Promise의 then 메서드를 체인형식으로 호출하는 것 보다 가독성이 훨씬 좋아진다.
await 키워드는 async 내부에서만 사용 할 수 있다.
예제 1 : 간단한 async / await 구현
function getGame(game) {
return new Promise((resolve, reject) => {
setTimeout(()=>{
resolve(game);
}, 1000);
});
}
async function statGame() {
const result = await getGame("SuperMario start");
// await 오른쪽에는 Promise가 오고 그 promise가 처리될대까지 기다린다.
console.log(result);
}
console.log("실행");
statGame();
예제 2 : Promise에서 만든 햄버거 주문 과정을 async & await으로 변경해보자.
const liceburger = () => {
return new Promise((res, rej) => {
setTimeout(() => {
res("라이스버거 완성");
}, 1000);
});
};
const bulgogiburger = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("불고기버거 완성");
}, 3000);
});
};
const tomatobuger = (message) => {
console.log(message)
return new Promise((res, rej) => {
setTimeout(() => {
res("토마토버거 완성");
}, 2000);
});
};
console.log("주문 시작");
// async를 사용 했을때와 then을 사용 했을때 비교
async
async function makeFood() {
const makeburger1 = await liceburger();
const makeburger2 = await bulgogiburger(makeburger1);
const makeburger3 = await tomatobuger(makeburger2);
console.log(makeburger3);
console.log("모든 음식이 완성 되었습니다.")
}
then 을 사용했을때
liceburger()
.then(res => bulgogiburger(res))
.then(res => tomatobuger(res))
.then(res => console.log(res))
.catch(() => {console.log("현재 주문하신 음식의 재료가 소진되었습니다.")})
.finally(() => {console.log("모든 음식이 완성 되었습니다.")})
[async가 훨씬 가독성이 좋다.]
makeFood();
// 주문 시작
// 라이스버거 완성
// 불고기버거 완성
// 토마토버거 완성
// 모든 음식이 완성 되었습니다.
예제 3 : async & await 에서 then의 catch 문은 어떻게 사용 할 수 있을까? async & await 는 try catch 문을 사용해 준다.
console.log("주문 시작");
async function makeFood() {
// try 문을 시도하고 만약 에러가 발생하면 catch 구문을 실행해 준다.
try{
const makeburger1 = await liceburger();
const makeburger2 = await bulgogiburger(makeburger1);
const makeburger3 = await tomatobuger(makeburger2);
console.log(makeburger3);
} catch (e) {
console.log(e)
}
console.log("모든 음식이 완성 되었습니다.")
}
makeFood();
예제 4 : async & await 에 promise all 메서드도 사용해 보자!
console.log("주문 시작");
async function makeFood() {
// try 문을 시도하고 만약 에러가 발생하면 catch 구문을 실행해 준다.
try{
const result = await Promise.all([liceburger(), bulgogiburger(), tomatobuger()]);
console.log(result);
} catch (e) {
console.log(e)
}
console.log("모든 음식이 완성 되었습니다.")
}
makeFood();
// 주문 시작
// ['라이스버거 완성', '불고기버거 완성', '토마토버거 완성']
// 모든 음식이 완성 되었습니다.
● Generator : 함수의 실행을 중간에 멈췄다가 재개할 수 있는 기능이다.
예제 1 사용법 : Generator는 function 키워드 오른쪽에 * 시를 붙이고 내부에 yield 키워드를 사용합니다. yield 키워드에서 함수를 멈출 수 있습니다.
function* fn() {
console.log(1);
yield 1;
console.log(2);
yield 2;
console.log(3);
console.log(4);
yield 3;
return "finish"
}
const a = fn(); // 제네레이터 함수를 실행하면 제네레이터 객체게 반환된다.
// 제네레이터 함수를 실행하려면 함수.next를 사용해줘야 한다. 그렇게 하면
// 가장 가까운 yield 문을 만날때까지 실행되고 데이터 객체를 반환 한다.
// 반환된 데이터 객체에는 value와 done property를 갖는데 value는 yield 오른쪽에 있는 값이다.
// 만약 값을 생략하면 undefined가 나온다
// done은 함수 코드가 끝났는지 나타내며, 실행이 끝났으면 true 그렇지 않으면 false를 반환한다.
console.log(a.next()); // 1 {value: 1, done: false}
console.log(a.next()); // 2 {value: 2, done: false}
console.log(a.next()); // 3 4 {value: 3, done: false}
console.log(a.next()); // {value: 'finish', done: true}
// 제네레이터는 next 메서드 외에 retrun 과 throw 메서드를 갖고 있다.
// retrun 메서드는 그 즉시 done 속성값을 true로 반환해준다. 그래서 이후에 next로 실행해도 value
// 값은 undefined가 나오게 된다.
// throw도 마찬가지로 done을 true로 바꿔준다.
iterable : 반복이 가능하다
조건 - 메서드 Symbol.iterator가 구현되어 있어야 한다 , Symbol.iterator 는 iterator를 반환해야 한다.
iterator
조건 - next 메서드를 가진다 , next 메서드는 value와 done 속성을 가진 객체를 반환한다 , 작업이 끝나면 done은 true가 된다.
}