※ 깃허브 레포지토리명과 프로젝트명은 같아야 함
다를 경우 : 터미널에서 npm install
입력, node modules 라는 폴더가 생김
그 후 프로젝트 종료
탐색기로 가서 해당 프로젝트의폴더 내의 .idea
폴더 -> 프로젝트명.iml
파일 복사 -> 프로젝트 폴더 바깥에 붙여넣은 후 레포지토리명과 동일하게 iml파일 이름을 바꾼 후 내용 편집 -> 해당 iml 파일 내부의 프로젝트명을 모두 레포지토리명과 동일하게 바꿔줌
.iead
폴더 내부의 vcs.xml
, workspace.xml
등의 모든 파일의 내용도 동일하게 확인해서 프로젝트명으로 되어있는 부분을 레포지토리명으로 바꿔줌
구성편집 -> 스크립트:start
ES6 버전에서 추가된 object 타입의 사용 방식
// Destructuring.js
console.log('----- ES5 -----');
var x = 0;
var y = 0;
var obj = {x: x, y: y};
console.log(obj);
var randomKeyString = 'other';
var combined = {};
combined['one' + randomKeyString] = 'some value';
console.log(combined);
console.log('\n----- ES6 -----');
var x = x;
var y = y;
// object 생성 시 키값을 설정하지 않으면 변수명이 키값으로 설정됨
var obj = {x, y}; // ES5) x --> 키이름, 변수명
console.log(obj);
// object 타입 생성 시 대입 연산자 오른쪽에서 바로 키와 값을 설정하여 object 타입에 데이터를 추가하는 것이 가능
var randomKeyString = 'other';
var combined = {['one' + randomKeyString]: 'some value'};
console.log(combined);
console.log('\n----- ES5 -----');
var obj2 = {
methodA: function () { console.log('A');},
methodB: function () { return 0;}
};
console.log(obj2);
obj2.methodA();
obj2.methodB();
데이터 집어넣을때 익명함수 안써도 되고 멤버 메서드 쓰듯 바로 쓰면 됨
console.log('\n----- ES6 -----');
var obj2 = {
methodA() { console.log('A');},
methodB() { return 0;}
}
console.log('\n----- 구조분해할당 -----');
console.log('\n----- ES5 -----');
var list = [0, 1];
var item1 = list[0];
var item2 = list[1];
var item3 = list[2] || -1;
console.log(item1); // 0
console.log(item2); // 1
console.log(item3); // -1
// 데이터 스왑시 임시변수(tmp) 필요
var temp = item2;
item2 = item1;
item1 = temp;
console.log(item1); // 1
console.log(item2); // 0
var obj = {
key1: 'one',
key2: 'two'
};
var key1 = obj.key1;
var key2 = obj.key2;
var key3 = obj.key3 || 'default key3 value';
var newKey1 = key1;
console.log(key1); // one
console.log(key2); // two
console.log(key3); // default key3 value
console.log(newKey1); // one
var list = [0, 1];
// 대입 연산자 왼쪽에 [] 를 사용하여 그 안에 배열을 쓰듯이 변수명을 입력하면
// 대입연산자 오른쪽의 데이터를 하나씩 꺼내어 내입 연산자 왼쪽의 변수명에 각각 저장됨
var [item1, item2, item3 = 1] = list; // = var [item1, item2, item3 = 1] = [0, 1]
console.log(item1); // 0
console.log(item2); // 1
console.log(item3); // 1
// 확장 표현식을 사용하여 임시 변수 없이 2개의 변ㅅ누의 값을 서로 변경함
[item2, item1] = [item1, item2];
console.log(item1); // 1
console.log(item2); // 0
// 배열의 확장 표현식과 동일하게 object 타입에서도 사용이 가능함
// 대입 연산자 왼쪽에 {} 을 사용하고 변수명을 입력하면, 대입 연산자 오른쪽의 object 타입의 키와 같은 변수명에 데이터를 저장함
// 키 이름 생략 시, 변수명을 키 이름으로 사용하는 법칙 때문임
// : <- 기호를 사용 시 새로운 변수명으로 적용
// = <- 기호를 사용 시 기본값으로 설정
var {key1: newKey1, key2, key3 = 'default key3 value'} = obj; // obj = { key1: 'one', key2: 'two'}
console.log(newKey1); // one
console.log(key2); // two
console.log(key3); // default key3 value
var [item, ...otherItems] = [0, 1, 2];
console.log(item); // 0
console.log(otherItems); // [1, 2]
var {key1, ...others} = {key1: 'one', key2: 'two'};
console.log(key1); // one
console.log(others); // {key2: 'two'}
자바의 클래스보다는 간소화 된 방식이지만 ES6 부터는 자바스크립트에서도 Class 키워드를 지원함
constructor(매개변수)
: 자바스크립트 클래스의 생성자, 자바스크립트의 생성자는 이름을 지정할 수 없음
extends
: 자바스크립트의 클래스도 상속을 지원함
// Class.js
// 클래스 선언
class Shape {
// 정적 멤버, 클래스명.정적멤버명 으로 사용
static create(x, y) {
return new Shape(x, y);
}
// 멤버변수 선언 - let, const 등 안붙여도 되는 이유 : 여기서 name 은 '키' 이다!
name = 'Shape';
// 생성자, 이름은 constructor 로 고정임
// 생성자에서 this.변수명 을 입력 시, 멤버 변수가 선언됨
constructor(x, y) { // 데이터타입은 안써도 자동으로 인식함(자바스크립트의 장점)
this.move(x, y); // this : 객체 자기 자신을 의미함
}
move(x, y) { // 키 이름 안써도 됨 사실은 move(x: x, y: y)
this.x = x;
this.y = y;
}
area() {
return 0;
}
}
var s = new Shape(10, 20);
s.area();
s.move(100, 200);
console.log(s.name);
console.log(s.x);
console.log(s.y);
var s1 = Shape.create(0, 0);
s1.area();
s1.move(10, 20);
console.log(s1.name);
console.log(s1.x);
console.log(s1.y);
// 상속(extends)
class Circle extends Shape {
constructor(x, y, radius) {
// 부모
super(x, y);
// 멤버변수 생성
this.radius = radius;
}
area() {
if (this.radius === 0) {
return super.area();
}
return this.radius * this.radius; // 10 * 10
}
}
var c = new Circle(0, 0, 10);
console.log(c.area()); // 100
ES6에서 배열 관련 함수가 추가됨(forEach(), map())
forEach()
와 map()
은 반환값이 있냐 없냐의 차이만 있다.
forEach()
: 지정한 배열의 요소에 callBack으로 지정한 함수의 내용을 실햄하는 함수, 반환값이 없음
배열명.forEach(콜백함수(현재값이 저장될 변수, 현재 index, 현재 배열 내용) {
실행할 소스코드
})
map()
: forEach 와 같이 지정한 배열의 요소에 callBack으로 지정한 함수의 내용을 실행하고 그 결과값을 배열로 반환하는 함수
배열명.map(콜백함수(현재값이 저장될 변수, 현재 index, 현재 배열 내용) {
실행할 소스코드
return 반환값
})
const fruits = ['사과', '배', '복숭아'];
console.log('원본 배열 : ' + fruits); // 사과,배,복숭아
// 기존 방식
console.log('\n----- for문 사용 시 -----');
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
// 사과
// 배
// 복숭아
}
console.log('\n----- for ~ in 문 사용 시 -----');
for (const item in fruits) {
// 값이 아니라 key 를 넣기때문에 item을 넣어줘야함
console.log(fruits[item])
// 사과
// 배
// 복숭아
}
// forEach() 사용 방식
console.log('\n----- forEach 문 사용 시 -----');
fruits.forEach(function (item) {
console.log(item);
// 사과
// 배
// 복숭아
})
console.log('\n----- forEach 문 매개변수 여러개 -----');
fruits.forEach(function (item, index){
console.log(`index : ${index}, value: ${item}`);
// index : 0, value: 사과
// index : 1, value: 배
// index : 2, value: 복숭아
})
// 현재 배열 내용 값 넣기 예시
fruits.forEach(function (item, index, arrName) {
console.log(`current array : ${arrName}, index : ${index}, value : ${item}`);
// current array : 사과,배,복숭아, index : 0, value : 사과
// current array : 사과,배,복숭아, index : 1, value : 배
// current array : 사과,배,복숭아, index : 2, value : 복숭아
});
console.log('\n----- map 사용 -----\n');
const numbers = [4, 9, 16, 25];
console.log(`원본 배열 : `);
console.log(numbers); // [ 4, 9, 16, 25 ]
let data = numbers.map(function (item) {
console.log(`현재 값 : ${item}`); // 4 9 16 25
return item * 2;
});
console.log(`map 사용 후 데이터 :`);
console.log(data); //[ 8, 18, 32, 50 ]
console.log('\n----- map() 에서 매개변수 여러개 -----\n');
data = numbers.map(function (item, index) {
console.log(`index : ${index}, value : ${item}`);
// index : 0, value : 4
// index : 1, value : 9
// index : 2, value : 16
// index : 3, value : 25
return item * 2;
});
console.log('map 사용 후 데이터 : ');
console.log(data); // [ 8, 18, 32, 50 ]
data = numbers.map(function (item, index, current) {
console.log(`current array : ${current}, index : ${index}, value : ${item}`);
// current array : 4,9,16,25, index : 0, value : 4
// current array : 4,9,16,25, index : 1, value : 9
// current array : 4,9,16,25, index : 2, value : 16
// current array : 4,9,16,25, index : 3, value : 25
return item * 2;
});
console.log('map 사용 후 데이터 : ');
console.log(data); // [ 8, 18, 32, 50 ]
화살표 함수 : ES6 버전부터 사용되는 함수를 선언하는 새로운 방식
ES5 버전의 익명함수를 사용하여 함수를 생성하는 방식에서 변경되어 function 키워드를 생략하고, 매개변수와 코드블럭 사이에 =>
기호를 사용하는 방식
소스코드가 반환값 한 줄 일 경우 코드블럭을 생략할 수 있음
매개변수가 1개 인 경우, 매개변수의 괄호를 생략할 수 있음
사용법 1 :
변수명 = (매개변수1, 매개변수2, ...) => {
실행할 소스코드
return 반환값
}
사용법 2 : 리턴 키워드, 중괄호 생략
변수명 = (매개변수1, 매개변수2, ...) => 반환값;
사용법 3 : 매개변수가 1개일때 소괄호까지 생략
변수명 = 매개변수 => 반환값;
사용법 4 : 매개변수가 없을때 () 로 대체함
변수명 = () => 반환값;
ArrowFunction.js
// 기존 함수 선언 방식 1
function es5Func1(a, b) {
console.log(a + b);
return a + b;
}
// 기존 함수 선언 방식 2
var es5Func2 = function (a, b) {
console.log(a + b);
return a + b;
}
es5Func1(10, 20); // 30
es5Func2(100, 200); // 300
let data = es5Func1(10, 20) // 30
console.log(data); // 30
data = es5Func2(100, 200); // 300
console.log(data); // 300
console.log('\n----- es6 방식 -----')
// 화살표 함수 선언
const es6Func1 = (a, b) => {
console.log(a + b);
return a + b;
}
data = es6Func1(10, 20); // 30
console.log(`리턴 받은 값 : ${data}`); // 30
// 생략 방법 1
// 생략 전
const es6Func22 = (a, b) => {
return a + b
}
// --> 생략 후
const es6Func2 = (a, b) => a + b;
data = es6Func2(100, 200);
console.log(`리턴 받은 값 : ${data}`); // 300
const es6Func3 = (a, b) => console.log(a + b);
es6Func3(10, 20);
// 매개변수가 1개일때 : 소괄호도 생략가능
const es6Func4 = (a) => a * 2;
data = es6Func4(10);
console.log(`리턴 받은 값 : ${data}`);
const es6Func5 = a => a * 2;
data = es6Func5(10);
console.log(`리턴 받은 값 : ${data}`);
// 매개변수가 없을때 : = => 와 같이 아예 생략은 안되고 = () => 와 같이 사용
const es6Func6 = () => console.log('esFunc5() 실행');
es6Func6();
하나의 자바스크립트 파일에서 다른 자바스크립트의 내용을 사용하기 위한 방식.
자바스크립트는 원래 html 을 지원하기 위해서 개발된 언어였기 때문에 html 문서 내에서 <script></script>
또는 <script src='파일경로'> </script>
형태로 다른 자바스크립트의 내용을 사용했음.
자바스크립트가 발전하면서 자바스크립트를 단순히 웹에서만 사용하는 것이 아니게 되어,
외부 자바스크립트 내용을 사용하기 위한 방법이 여러가지로 개발됨.
ES6 버전부터 export, import 를 지원함.
자바스크립트 파일 하나하나를 모듈이라고 함.
하나의 모듈에는 하나의 export default 가 존재함.
html 문서 내에서 import 를 사용하고자 할 경우 <script type="module">
을 사용하여 해당 파일이 모듈을 사용한다는 것을 알려줘야 함
<script type="module" src="파일경로><script>
node.js 가 ES6 버전이 나오기 이전부터 모듈화 시스템을 사용하고 있었음.
node.js 가 기본적으로 사용하던 방식이 CommonJS 방식의 모듈 시스템을 사용하고 있었음
ES6 가 발표되면서 [ import/export ] 를 지원하게 됨.
기본 방식은 CommonJS 으로 사용되고 ES6 방식으로 사용하려면
확장자를 .mjs 로 변경하여 사용하던지,
package.json 파일에 type: "module" 을 추가하여 설정을 해야 함.
export
: 변수, 함수, 클래스를 다른 자바스크립트 파일에서 사용할 수 있도록 설정
사용법 :
export 함수명; // <-- 함수명이라고 썼지만 변수/함수 모두 사용 가능
export {함수명1, 함수명2, ...};
export default 함수명;
import
: 다른 자바스크립트 파일이 제공하는 변수, 함수, 클래스를 불러와서 사용하도록 설정
사용법 :
↓↓ 일반 export 로 지정된 것을 불러올 때 ↓↓
import {함수명1, 함수명2, ...} from 파일경로; // <-- 함수명이라고 썼지만 변수/함수 모두 사용 가능
↓↓ export default 로 지정된 것을 불러올 때 ↓↓
import 함수명 from 파일경로;
export, import 하는 파일 모두 확장자명을 .js가 아니라 .mjs로 수정해야 한다.
터미널에서 실행할때도 파일명 끝에 .mjs 붙여줘야 정상적으로 실행이 됨
파일생성(설정방법 2가지) : MyMod1.mjs, MyMod2.mjs
파일생성(사용) : ModuleUse.mjs
방법1(MyMod1) : 외부로 출력하고자 하는 변수 및 함수, 클래스에 export 를 접두사로 붙임
방법2(MyMod2) : 변수, 함수, 클래스를 기존에 사용하듯이 다 선언하고, 파일의 끝에서 export 를 진행
방법2를 보편적으로 사용함
MyMod1.mjs
// MyMod1.mjs
// export 로 설정 방법은 두 가지.
// export 로 설정하는 방법 1
// 외부로 출력하고자 하는 변수 및 함수, 클래스에 export 를 접두사로 붙임
export const name = '아이유';
export const gender = '여성';
export const job = '가수';
export const getInfo = () => console.log(`이름 : ${name}, 성별 : ${gender}, 직업 : ${job}`);
// MyMod2.mjs
// export 로 설정하는 방법 2
// 변수, 함수, 클래스를 기존에 사용하듯이 다 선언하고, 파일의 끝에서 export 를 진행
const num1 = 10;
const num2 = 20;
const sum = () => num1 + num2;
const sub = () => num1 - num2;
export {num1, num2, sum};
export default sub;
// ModuleUse.mjs
import {name, job, gender, getInfo} from "./MyMod1.mjs";
import {num1, num2, sum} from "./MyMod2.mjs";
import sub from "./MyMod2.mjs";
console.log(name); // 아이유
console.log(gender); // 여성
console.log(job); // 가수
getInfo(); // 이름 : 아이유, 성별 : 여성, 직업 : 가수
console.log(`첫번째 숫자 : ${num1} + 두번째 숫자 : ${num2}의 값 : ${sum()}`);
// 첫번째 숫자 : 10 + 두번째 숫자 : 20의 값 : 30
console.log(`sub() 실행 : ${sub()}`); // -10
Promise : 자바스크립트에서 비동기 함수의 동기 처리를 하기 위해서 사용하는 객체
자바스크립트는 기본적으로 1 쓰레드
비동기 처리
방식을 사용하고 있음 (특정 로직의 실행이 끝날 때까지 기다려주지 않고 나머지 코드를 먼저 실행하는 것이 비동기 처리이다.)
자바스크립트에서 순차적으로 실행을 하고 싶을 경우 콜백 함수
를 이용하여야 함
순차적으로 실행할 것이 많아지게 되면 콜백지옥
이라고 불리는 형태가 만들어지게 됨
프로미스는 이러한 콜백 지옥을 해결하기 위해서 사용하는 객체임
promise 에는 pending
, fulfilled
, rejected
3가지 상태가 존재함
pending
: 대기 상태, 비동기 함수가 실행되고, 아직 처리가 완료되지 않은 상태fulfilled
: 완료 상태, 비동기 함수가 실행된 후 정상적으로 처리가 완료된 상태rejected
: 거부 상태, 비동기 함수가 실행된 후 오류가 발생한 상태promise 에는 실행 시 콜백함수가 실행되고, 해당 콜백함수의 매개변수로 resolve()
, reject()
이라는 함수를 제공함
resolve(매개변수)
: 프로미스 실행 후 fulfilled 상태일 경우 실행하는 함수로 나중에 then()
함수를 제공함reject(매개변수)
: 프로미스 실행 후 rejected 상태일 경우 실행하는 함수로 나중에 catch()
함수를 제공함프로미스에는 완료 및 오류처리를 위해서 then()
, catch()
함수를 제공하고 있음
then(매개변수)
: 비동기 함수 실행이 완료된 후 실행되는 함수
catch(매개변수)
: 비동기 함수 실행이 거부된 후 실행되는 함수
사용법
선언 :
function 프로미스를 사용할 함수명(매개변수) {
return new Promise(function(resolve, reject) {
비동기 통신 소스...
비동기 통신 결과에 따라 resolve(), reject();
});
}
실행 :
프로미스를 사용한 함수명()
.then(function(매개변수) {
성공 시 실행할 내용
})
.catch(function(매개변수) {
실패 시 실행할 내용
});
자바스크립트의 이벤트 처리 방식 참고 : https://manbalboy.github.io/front/javascript01.html
V8에서 한줄씩 실행을 하다가 이벤트를 만나면 이벤트Queue에 넘기고 V8은 다시 실행해야되는 코드로 돌아가서 그 다음 줄 부터 하나씩 실행함
이벤트 Queue 에서는 먼저 들어온것부터 Event Loop 돌림
워크 쓰레드에서 실행 후 결과를 이벤트 큐로 다시 보냄 -> 이벤트 큐가 다시 실행 -> 끝나면 이벤트 처리가 완전히 끝냈을때 실행하는 부분에 알려줌 (= 콜백)
ajax에서의 success: function() <- function 이 콜백함수임
이것이 비동기 처리임
단점은 콜백지옥이 생김
https://velog.io/@seul06/JavaScript-%EC%BD%9C%EB%B0%B1-%EC%A7%80%EC%98%A5
이것을 해결하고자 만들어진 것이 promise 이다.
npm install jquery
입력App.js
import './App.css';
import {getData, getData1} from "./es6/Promise";
function App() {
getData();
return (
<div className="App">
</div>
);
}
export default App;
// import
import React from "react";
import $ from 'jquery';
// 프로미스 객체를 사용할 함수
function getData() {
// 콜백함수 resolve, reject
return new Promise(function (resolve, reject) {
const data = 100;
// resolve 를 실행하게되면 .then ~ 부분이 실행이 되고, reject 를 실행하게 되면 .catch ~ 부분이 실행이 됨
resolve(data);
// reject(data);
});
}
getData()
.then(function (data) {
console.log(`프로미스 사용 반환값 : ${data}`);
})
.catch(function (err) {
console.log(`프로미스 사용 오류 시 출력 : ${err}`)
});
const getData1 = function () {
return new Promise(function (resolve, reject) {
$.ajax({
url: 'http://localhost:8080/async/data1',
type: 'post',
success: function (data) {
console.log('통신 성공');
resolve(data);
},
error: function () {
reject('오류 발생!');
}
});
});
};
// export 선언
export {getData, getData1};
getData1()
.then(function (data) {
console.log(data);
})
.catch(function (err) {
console.log(err);
});
@CrossOrigin(origins = "http://localhost:3000")
어노테이션 추가@CrossOrigin(origins = "http://localhost:3000")
@ResponseBody
@RequestMapping(value = "/async/data1", method = RequestMethod.POST)
public String asyncData1() {
return "서버와 통신 성공";
}
자바스크립트 비동기 처리와 콜백 함수 쉽게 이해하기
https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/
자바스크립트 Promise 쉽게 이해하기
https://joshua1988.github.io/web-development/javascript/promise-for-beginners/