먼저 함수를 선언할 때는 선언적 함수와 익명 함수 두가지의 형태가 있는데,
선언적 함수란 일반적으로 이름을 가지고 선언된 함수로 아래와 같은 형태이다.
function add(first, second) {
return first + second;
}
이 함수를 콘솔에 찍어보면 아래처럼 나오게 된다.
> add
< ƒ add(first, second) {
return first + second;
}
반대로 익명 함수는 함수의 형태지만 이름이 명시되지 않은 함수이다.
var add = function(first, second) {
return first + second;
}
익명 함수를 콘솔에 찍어보면 아래처럼 나오게 된다.
> add
< ƒ (first, second) {
return first + second;
}
두 함수가 직접적인 차이를 보이는 시점은 런타임(코드를 실행할 때) 확인할 수 있다.
선언적 함수는 아래 코드처럼 함수를 실행시키는 코드를 먼저 위치시켜도 글로벌(전역)에 등록되어 나중에 선언하는 것이 가능하다.
add(1,2);
function add(first, second) {
return first + second;
}
익명 함수의 경우, 다른 코드와 같이 런타임시에 순서대로 실행되기 때문에 TypeError(타입 에러)를 일으키게 된다.
add(1,2);
var add = function(first, second) {
return first + second;
}
// Uncaught TypeError: add is not a function
ES6 화살표 함수는 익명 함수를 선언하여 변수에 대입하는 방법과 유사한데, 몇 가지 장점을 가지고 있다.
첫 번째는 인자를 담고 있는 괄호와 스코프를 가리키는 화살표로 표현되어 직관적인 syntax 스타일로 가독성이 향상된 점이다.
위에서 사용한 코드를 화살표 함수로 변형하면 아래와 같다.
var add = (first, second) => {
return first + second;
};
// 바로 값을 리턴하는 경우에는 중괄호({})와 return을 생략할 수 있다.
var add = (first, second) => first + second;
또한 커링과 같이 함수안에 또 다른 함수를 리턴하는 함수를 더 직관적인 구조로 만들 수 있다.
// ES5에서의 커링 함수
var addMore = function(firstNum) {
return function(secondNum) {
return firstNum + secondNum;
};
};
// 화살표 함수를 사용한 커링 함수
var addMore = (firstNum) => (secondNum) => {
return firstNum + secondNum;
}
// 혹은 값을 바로 리턴하기 때문에 아래처럼 더 줄일 수 있다.
var addMore = (firstNum) => (secondNum) => firstNum + secondNum;
var addTwo = addMore(2);
> addTwo(3);
< 5
> addTwo(4);
< 6
화살표 함수의 또다른 장점은 this
바인딩(binding) 과정을 포함하고 있어 자동으로 this
의 범위를 유지시켜 준다.
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
log() {
console.log(this === myPoint); // => true
// setTimeout(function() {
setTimeout(() => {
console.log(this === myPoint); // => true
console.log(this.x + ':' + this.y); // => '95:165'
}, 1000);
}
}
var myPoint = new Point(95, 165);
myPoint.log();
Point
안의 메소드 log
에서 setTimeout
의 콜백 함수가 일반 function 이라면 this
가 window
로 되어 있어 바인딩을 해주어야 한다.
이 때 화살표 함수를 이용하면 자동으로 상위 context인 Point
로 정의된다.
객체 확장 표현식은 객체의 키-값을 선언하는 과정을 간략화하였다.
아래 예시 코드들은 이곳에서 참조하였습니다.
var x = 0;
var y = 0;
// 이런 중복되는 방식을 간략화하여
var obj = { x: x, y: y};
// 아래처럼 변환시킬 수 있다.
var obj = { x, y };
var randomKeyString = 'other';
// 객체를 선언하고 키-값을 따로 할당하는 과정을 간략화하면
var combined = {};
combined['one' + randomKeyString] = 'some value';
// 아래와 같이 표현할 수 있다.
var combined = {
['one' + randomKeyString]: 'some value',
};
// 객체에 함수를 값으로 받을 경우에는
var obj2 = {
methodA: function() { console.log('A'); },
methodB: function() { return 0; },
};
// 바로 함수를 선언하는 방식으로 간략화되었다.
var obj2 = {
x,
methodA() { console.log('A'); },
methodB() { return 0; },
};
객체나 배열에서 특정 자료를 분해해서 할당하는 '구조 분해 할당' 과정도 ES6에서 간소화되었다.
// 배열
var list = [0,1];
// ES5에서는 배열의 각 요소를 매번 할당해주어야 했다.
var item1 = list[0];
var item2 = list[1];
var item3 = list[2] || -1;
// ES6에서는 분해하려는 요소들을 묶어서 한 번에 할당할 수 있다.
var [
item1,
item2,
item3 = -1,
] = list;
// 요소를 서로 바꾸는(swap) 방식도 변수를 임시로 선언하지 않고
var temp = item2;
item2= item1;
item1 = temp;
// 바로 변경할 수 있게 되었다.
[item2, item1] = [item1, item2];
// 객체
var obj = {
key1: 'one',
key2: 'two',
};
// 객체도 마찬가지로 매번 선언-할당이 아닌,
var key1 = obj.key1;
var key2 = obj.key2;
var key3 = obj.key3 || 'default key3 value';
var newKey1 = key1;
// 통합하여 한번에 분해할 수 있게 되었다.
var {
key1: newKey1,
key2,
key3 = 'default key3 value',
} = obj;
// 요소의 인덱스 순으로 분해도 가능하다.
var [item1, ...otherItems] = [0, 1, 2]; // otherItems = [1, 2]
var { key1, ...others } = { key1: 'one', key2: 'two' }; // others = { key2: 'two' }
"어떤 파일이나 코드가 다른 파일이나 코드를 필요로 하는 것을 의존성(Dependency)이라고 하는데 기존 자바스크립트는 라이브러리나 모듈을 관리하는 방법이 매우 불편했습니다."
예전에는 html 문서에 <script></script>
태그 엘리먼트를 이용하여 필요로 하는 파일을 참조하도록 하였다.
이 때, 만약 참조하는 파일에서 선언한 변수나 함수를 필요로 하는 파일을 html 문서에 먼저 위치시킨다면 런타임시에 에러가 발생하게 된다. 또한 해당 파일들은 모두 window(전역) 객체의 속성으로 서로 간의 독립성이 떨어지게 된다.
기존의 또다른 모듈을 정의하는 방법으로는 require, module, exports
를 사용하는 CommonJS 가 있다. 특정 변수나 그 변수의 속성으로 내보낼 객체를 세팅해주어야 한다.
var module = require('./MyModule');
function Func() {
module();
}
module.exports = new Func();
여러 개의 객체를 내보낼 경우, exports
변수의 속성으로 할당해야하고,
딱 하나의 객체를 내보낼 경우, module.exports
변수 자체에 할당한다.
ES6에서 이러한 모듈 내보내기/불러오기를 자체적으로 지원할 수 있게 만든 방식이 import
구문이다. import
구문은 "script 엘리먼트 없이 연결된 파일 및 의존 파일을 먼저 모두 내려 받고 코드를 구동 하도록" 변경하여 앞서 소개된 참조 순서와 관련된 문제를 방지한다.
import MyModule from './MyModule';
import { ModuleName } from './MyModule';
import { ModuleName as RenamedModuleName } from MyModule';
function Func() {
MyModule();
}
export const CONST_VALUE = 0;
export default new Func();
https://yolo2429.tistory.com/225