기존방식
var string1 = '안녕하세요';
var string2 = '반갑습니다';
var greeting = string1+ '' + string2;
var product = { name: '도서' , price: '4200원'};
var message = '제품' + product.name + '의 가격은 ' + product.price + '입니다';
var multiline = '문자열1\n문자열2';
var value1 = 1;
var value2 = 2;
var boolvalue = false;
var operator1 = '곱셈값은 ' +(value1*value2);
var operator2 = '불리언값은 ' +(boolvalue ? '참' : '거짓');
ES6
var string1 = '안녕하세요';
var string2 = '반갑습니다';
var greeting = `${string1} ${string2}`;
var product = { name: '도서' , price: '4200원'};
var message = `제품 ${product.name}의 가격은 ${product.price} 입니다`;
var multiline = `문자열1
문자열2`;
var value1 = 1;
var value2 = 2;
var boolvalue = false;
var operator1 = `곱셈값은 ${value1 * value2}`;
var operator2 = `불리언값은 ${boolvalue ? '참' : '거짓'}`;
기존방식
var array1 = ['one', 'two'];
var array2 = ['three', 'four'];
var combined = [array1[0], array1[1], array2[0], array2[1]];
//concat은 배열이나 문자열을 합칠때 사용합니다. 새로운 배열을 만들어 값을 넣어줍니다.
var combined = array1.concat(array2);
var combined = [].concat(array1, array2);
var first = array1[0];
var second = array1[1];
var three = array1[2] || 'empty';
function func() {
var args = Array.prototype.slice.call(this, arguments);
var first = args[0];
var other = args.slice(1, args.length);
}
ES6
var array1 = ['one', 'two'];
var array2 = ['three', 'four'];
const combined = [...array1, ...array2];
const [first, second, three = 'empty', ...other] = array1;
func1(...args){
var [first,...others] = args
}
기존방식
var objectOne = { one: 1, two: 2, other: 0 };
var objectTwo = { three: 3, four: 4, other: -1 };
var combined = {
one: objectOne.one,
two: objectOne.two,
three: objectTwo.three,
four: objectTwo.four,
};
var combined = Object.assign({}, objectOne, objectTwo);
//combined ={one:1,two:2,three:3,four:4,other:-1};
var combined = Object.assign({}, objectTwo, objectOne);
//combined ={one:1,two:2,three:3,four:4,other:0};
var others = Object.assign({}, combined);
delete others.other;
// others = {one:1,two:2,three:3,four:4};
ES6
var objectOne = { one: 1, two: 2, other: 0 };
var objectTwo = { three: 3, four: 4, other: -1 };
var combined = {
...objectOne,
...objectTwo,
};
//combined ={one:1,two:2,three:3,four:4,other:-1};
var combined = {
...objectTwo,
...objectOne,
};
//combined ={one:1,two:2,three:3,four:4,other:0};
var { other, ...others } = combined;
가변 변수 let 과 불변 변수 const를 사용하는 이유
1. var 키워드는 생략이 가능하여 전역변수를 남발하게 되는 경우가 존재한다.
//키워드 생략 가능
num = 1;
// 변수의 중복 선언 가능
var favorite = 'dog';
var favorite = 'cat';
//중복 선언 허용
2. var 같은 경우 선언되지 않은 변수에 대한 참조가 가능합니다.
console.log(a); // undefined. 즉 a는 이미 선언된 상태이다.
var a;
console.log(b); // ReferenceError: b is not defined
let b;
3. function level Scope 문제
var myList = [];
for(var i=0; i<5; i++){
myList.push(i);
}
console.log(i); // 5
let 키워드
가변 변수로써 값을 재할당이 가능하며 키워드 자체만 보고도 수정가능한 변수라는 것을 인지할수 있다. 그외에도 중복값을 할당하면 에러가 발생하고 Block Level Scope 이다.
const 키워드
불변 변수로써 처음 선언시 값을 할당하여야 하며 Block Level Scope 이다.
값을 다시 할당하는것은 가능하나, 무결성을 유지하기 위해 값을 재할당 해야 될 경우 새로운 const를 만드는 방식으로 진행하는것이 옳다
function Shape(x, y) {
this.name = 'Shape';
this.move(x, y);
}
//static 함수를 선언하는 예제
Shape.create = function (x, y) {
return new Shape(x, y);
};
//인스턴스 함수를 선언하는 예제
Shape.prototype.move = function (x, y) {
this.x = x;
this.y = y;
};
Shape.prototype.area = function () {
return 0;
};
//혹은 밑으로 대체가능
Shape.prototype = {
move: function (x, y) {
this.x = x;
this.y = y;
},
area: function () {
return 0;
},
};
// 기존 자바스크립트에서는 함수를 생성자형태로 선언한 다음 상속이 필요한 변수나 함수를 prototype 객체에 할당하는 방법을 사용 했습니다.
// prototype 객체는 new 연산자로 생성되는 객체 안에서 this 연산자의 함수 및 변수 선언 위치를 참조할 수 있는 요소인데, 이 특징을 이용한 것
function Circle(x, y, radius) {
Shape.call(this, x, y);
this.name = 'Circle';
this.radius = radius;
}
Object.assign(Circle.prototype, Shape.prototype, {
area: function () {
return this.radius * this.radius;
},
});
var c = new Circle(0, 0, 10);
c.area(); //100
ES6
class Shape {
static create(x, y) {
return new Shape(x, y);
}
name = 'Shape';
// ES7에 포함된 클래스 확장 표현으로 constructor() 함수 안에 this.name = 'Shape'로 클래스 변수를 선언하는 것과 동일한 작업
constructor(x, y) {
this.move(x, y);
}
move(x, y) {
this.x = x;
this.y = y;
}
area() {
return 0;
}
}
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;
}
}
Java언어와 유사한 패턴을 보여줍니다.
하지만 다중 상속이나 인터페이스는 지원하지 않기에 주의해주시길 바랍니다.
화살표 함수는 ES6에 추가된 표현식을 사용하는 함수로 화살표 기호 =>로 함수를 선언합니다.
기존 자바스크립트에서 함수를 선언하는 2가지 방식
function add(first, second) {
return first + second;
}
//typeof add === 'function'
var add = function (first, second) {
return first + second;
};
//typeof add === 'function'
아래 이미지를 보면 위의 펑션은 add라는 이름을 가지고 있고 하나는 익명함수이다.

화살표 함수 사용 방법
화살표 함수는 익명 함수를 선언하며 변수에 대입하는 방법과 유사합니다. 하나 다른 점은 function 키워드를 생략하고 인자(()) 블록과 본문({}) 블록 사이에 =>를 표시한다는 것입니다.
var add = (first, second) => {
return first + second;
};
var add = (first, second) => first + second;
var addAndMultiple = (first, second) => ({ add: first + second, multiply: first * second });
//반환값이 객체라면 괄호로 결괏값을 감싸 간결하게 표현할 수 있습니다.
// 이후에 배울 커링과 같은 디자인 패턴에서 계단식 함수 선언 구조가 만들어지지 않게 해준다는 장점이 있습니다.
function addNumber(num){
return function (value){
return num + value;
};
}
var addNumber = num => value => num + value;
//또한 화살표 함수는 this범위로 생기는 오류를 피하기 위해 bind() 함수를 사용하여
//this객체를 전달하는 과정을 포함하고 있습니다.
class Myclass{
value = 10;
constructor() {
var addThis2 = function(first, second){
return this.value + first + second;
}.bind(this);
var addThis3 = (first,second) => this.value + first + second;
//기존 사용방법
var x = 0;
var y = 0;
var obj = { x: x, y: y };
var randomKeyString = 'other';
var combined = {};
combined['one' + randomKeyString] = 'some value';
var obj2 = {
x: x,
methodA: function () {
console.log('method A');
},
methodB: function () {
return 0;
},
};
//ES6
var combined = {
['one' + randomKeyString]: 'some value',
};
var obj2 = {
x,
methodA() {
console.log('method A');
},
methodB() {
return 0;
},
};
//기존 자바스크립트 구조분해
var list = [0, 1];
var item1 = list[0];
var item2 = list[1];
var item3 = list[2] || -1;
var temp = item2;
item2 = item1;
item1 = temp;
var obj = {
key1: 'one',
key2: 'two',
};
var key1 = obj.key1;
var key2 = obj.key2;
var key3 = obj.key3 || 'default key3 value';
var newKey1 = obj.key1;
//ES6 구조 분해와 구조 할당 사용법
var list = [0, 1];
var [item1, item2, item3 = -1] = list;
[item2, item1] = [item1, item2];
var obj = {
key1: 'one',
key2: 'two',
};
var { key1: newKey1, key2, key3 = 'default Key3 Value' } = obj;
// key1: newKey1 이렇게 구조분해 할당할경우 key1은 생성되지 않고 newKey1만 생성된다.
var [item1, ...otherItems] = [0, 1, 2];
var { key1, ...otherKeys } = { key1: 'one', key2: 'two' };
//otherItems = [1,2];
//others = {key2: 'two'};
구조 분해와 구조 할당은 함수 인잣값을 다루거나 JSON 데이터를 변환할 때 유용하게 사용하므로 꼭 기억하는 것이 좋습니다.
기존의 자바스크립트에서 라이브러리나 모듈의 의존성 관리를 script 엘리먼트를 통하여 했습니다.
<html>
<head>
<script src="./jquery.min.js"></script>
<script src="./math.js" ></script>
<script src="./app.js" ></script>
</head>
</html>
만약 math.js 내에 전역변수를 app.js에서 사용할 경우 위와 같이 차례대로 되어있다면 문제가 없겠지만 순서를 바꾼다면 오류가 발생합니다. 이러한 문제를 해결하기위해 ES6에선 import 구문을 통해 script 엘리먼트 없이 연결된 파일 및 의존 파일을 모두 내려받고 코드를 구동하도록 변경하였습니다
import MyModule from './MyModule.js';
import {ModuleName} from './MyModule.js';
...
//자주 사용하는 배열 함수 forEach(),map(),reduce()입니다.
//기존 자바스크립트로 쿼리 스트링 'banana=10&apple=20&orange=30' 을 & 문자를 기준으로
// 분리하여 객체에 담아 반환하는 parse함수를 선언한것입니다.
function parse(qs) {
var queryString = qs.substr(1); //queryString = 'banana=10&apple=20&orange=30'
var chunks = qs.split('&'); // chunks = ['banana=10','apple=20','orange=30']
var result = {};
for (var i = 0; i < chunks.length; i++) {
var parts = chunks[i].split('=');
var key = parts[0]; //key = 'banana'
var value = parts[1]; // value = '10'
result[key] = value; // result = {banana = '10'}
}
return result;
}
//ES6 , (10,20,30을 문자열이 아닌 숫자로 반환)
function parse(qs) {
const queryString = qs.substr(1); //queryString = 'banana=10&apple=20&orange=30'
const chunks = qs.split('&'); // chunks = ['banana=10','apple=20','orange=30']
let result = {};
chunks.forEach((chunks) => {
const parts = chunks.split('=');
const key = parts[0];
const value = Number.isNaN(Number(parts[1])) ? parts[1] : Number(parts[1]);
//구조분해로 더 간결한 코드
const [key, value] = chunks.split('=');
result[key] = value;
});
return result;
}
//map() 함수 사용법 기존은 let result 로 가변 변수를 사용했으나
//map 함수로 const 불변 변수만을 사용하는 방법이 있습니다.
//map 함수는 배열을 받아 새로운 배열을 반환하는 함수입니다.
function parse(qs) {
const queryString = qs.substr(1); //queryString = 'banana=10&apple=20&orange=30'
const chunks = qs.split('&'); // chunks = ['banana=10','apple=20','orange=30']
const result = chunks.map((chunks) => {
const [key, value] = chunks.split('=');
return {key:key, value:value};
});
return result;
}
//reduce() 함수 사용법
//객체로 반환 하고자 할때 사용합니다.
function parse(qs) {
const queryString = qs.substr(1); //queryString = 'banana=10&apple=20&orange=30'
const chunks = qs.split('&'); // chunks = ['banana=10','apple=20','orange=30']
return chunks
.map((chunks) => {
const [key, value] = chunks.split('='); // key ='banana',value = '10'
return { key, value }; //{key:'banana',value:'10'}
})
.reduce((result, item) => {
//result = {}, item = {key:'banana',value='10'}
result[item.key] = item.value; //result = {banana:'10'}
return result;
}, {});
}
map() 함수는 배열을 새로운 배열로 만드는데 사용하고,
reduce() 함수는 배열의 각 요소값을 순환 할당하면서 새로운 객체를 만드는데 사용가능합니다.
//기존 자바스크립트에서는 setTimeout() 함수를 이용해 비동기 작업을 처리했습니다.
function work1(onDone) {
setTimeout(() => onDone('작업1 완료!'), 100);
}
function work2(onDone) {
setTimeout(() => onDone('작업2 완료!'), 200);
}
function work3(onDone) {
setTimeout(() => onDone('작업3 완료!'), 300);
}
function ungentWork() {
console.log('긴급 작업');
}
// 함수 작동 순서 urgentWork() -> work1(100ms후) -> work2(200ms후) -> work3(300ms후)
// 이방식의 문제점은 100개의 비동기 작업이 존재할시 콜백 지옥,
// 계단 형식으로 함수가 자꾸 늘어나는 문제가 생깁니다.
work1(function (msg1) {
console.log('done after 100ms:' + msg1);
work2(function (msg2) {
console.log('done after 300ms:' + msg2);
work3(function (msg3) {
console.log('done after 600ms:' + msg3);
});
});
});
urgentWork();
// 작동은 동일하지만 Promise 클래스를 이용하여 비동기 처리 방식
const work1 = () =>
new Promise((resolve) => {
setTimeout(() => onDone('작업1 완료!'), 100);
});
const work2 = () =>
new Promise((resolve) => {
setTimeout(() => onDone('작업2 완료!'), 200);
});
const work3 = () =>
new Promise((resolve) => {
setTimeout(() => onDone('작업3 완료!'), 300);
});
function urgentWork() {
console.log('긴급 작업');
}
const nextWorkOnDone = (msg1) => {
console.log('done after 100ms:' + msg1);
return work2();
};
work1()
.then(nextWorkOnDone)
.then((msg2) => {
console.log('done after 200ms:' + msg2);
return work3();
})
.then((msg3) => {
console.log('done after 600ms:' + msg3);
});
urgentWork();
디바운스와 스로틀은 ES6 문법은 아닙니다.
디바운스는 어떤 내용을 입력하다가 특정시간 동안 대기하고 있으면 마지막에 입력된 내용을
바탕으로 서버 요청하는 방법입니다. 네이버나 구글 검색창에 자주 사용됩니다.
export function debounce(func, delay) {
let inDebounce;
return function (...args) {
if (inDebounce) {
clearTimeout(inDebounce);
}
inDebounce = setTimeout(() => func(...args), delay);
};
}
const run = debounce(val => console.log(val),100);
run('a');
run('b');
run(2);
// 100ms 이후
// 2
스로틀은 입력되는 동안에도 바로 이전에 요청한 작업을 주기적으로 실행한다는 것입니다.
Ex) 페이스북 무한 스크롤
function throttle(func, delay) {
let lastFunc;
let lastRan;
return function (...args) {
const context = this;
if (!lastRan) {
func.call(context, ...args);
lastRan = Date.now();
} else {
if (lastFunc) clearTimeout(lastFunc);
lastFunc = setTimeout(function () {
if (Date.now() - lastRan >= delay) {
func.call(context, ...args);
lastRan = Date.now();
}
}, delay - (Date.now() - lastRan));
}
};
}
var checkPosition = () => {
const offset = 500;
const currentScrollPosition = window.pageYOffset;
const pageBottomPosition = document.body.offsetHeight - window.innerHeight - offset;
if (currentScrollPosition >= pageBottomPosition) {
console.log('다음 페이지 로딩');
}
};
var infiniteScroll = throttle(checkPosition, 300);
window.addEventListener('scroll', infiniteScroll);