자바스크립트에서 함수를 만들 때는 function
키워드를 사용하여 정의할 수 있다.
기존 두 수의 합을 구하는 함수는 다음과 같다.
function sum(a+b){
return a+b;
}
ES6부터는 화살표 함수(arrow function)라는 새로운 문법 방식으로 함수를 만들 수 있게 되었다.
// 기존 함수
function f() {}
// 화살표 함수
const f = () => {};
위의 함수를 화살표 함수로 바꾸면 아래와 같다.
function sum(a+b){
return a+b;
}
const sum = (a, b) => a + b;
// 매개변수가 없는 경우
() => { ... }
// 매개 변수가 하나인 경우, 소괄호 생략 가능
a => { ... }
// 매개변수가 여러개인 경우, 소괄호 생략 불가능
(a, b) => { ... }
함수 몸체 내의 코드가 한 줄이고 단순히 return문 밖에 없다면 중괄호와 return 키워드를 생략할 수 있다.
(a) => {
return a * a;
};
// 함수 몸체가 한줄의 구문이라면 중괄호를 생략할 수 있으며 암묵적으로 return이 된다.
(a) => a * a;
객체 리터럴을 반환하려면 소괄호로 감싸야한다. 왜냐하면 중괄호 {}
쓰면 얘가 함수 블럭인지 객체 블럭인지 판단할 수 없다.
() => {
return { a: 1 };
};
() => ({ a: 1 });
// 매개변수 기본값
(a = 1, b = 2) => a + b;
// 나머지 매개변수
(...args) => args;
// 구조 분해 할당
([a, b] = [1, 2]) => a + b;
let age = prompt("나이를 알려주세요", 28);
let welcome = (age < 18>) ?
() => alert('안녕') :
() => alert("안녕하세요!");
welcome();
자바스크립트의 화살표 함수는 function 함수의 축약하여 표현하는 문법이지만, 일반적인 함수와 다른 몇 가지 고유한 특징을 가진다. 이러한 특징은 화살표 함수를 유용하게 만들기도 하지만, 함정이 되기도 하기 때문에 유의깊게 살펴봐야한다.
화살표 함수에서 this 키워드로 접근하면, 자신이 아닌 외부에서 값을 가져온다.
var name = "Meerkat";
let user = {
name: "dong",
// 일반 함수
sayHi: function () {
console.log(this.name);
},
};
user.sayHi(); // dong
var name = "Meerkat";
let user = {
name: "dong",
// 화살표 함수
sayHi: () => {
console.log(this.name);
},
};
user.sayHi(); // Meerkat
자바스크립트 함수의 arguments는 일반적인 함수가 호출될 때 전달된 인수들을 담고 있는 유사 배열 객체이다.
function argsFunc() {
console.log(arguments);
}
argsFunc(1, 2, 3); // [1, 2, 3]
화살표 함수는 arguments를 지원하지 않는다.
let argsFunc = () => {
console.log(argments);
};
argsFunc(1, 2, 3); // !Error
대신 나머지 매개변수(rest parameter)라는 문법을 사용하여 인수들을 배열로 받을 수 있다.
let argsFunc = (...args) => {
console.log(args);
};
argsFunc(1, 2, 3); // [1, 2, 3]
function User(name) {
this.name = name;
}
let user = new User("Meerkat");
console.log(user.name); // Meerkat
화살표 함수는 this가 없기 때문에 new와 함께 실행할 수 없다.
let User = (name) => {
this.name = name;
};
let user = new User("Alice"); // TypeError: User is not a constructor
따라서 화살표 함수는 객체를 생성하는 용도로 사용할 수 없다. 그래서 화살표 함수는 보통 콜백 함수나 익명 함수로서 사용되는 편이다.
화살표 함수는 일반 함수와 달리 자신만의 this를 가지지 않으므로 몇가지 제약이 생긴다.
this 참조를 자주 사용해야할 메서드 로직이라면 화살표 함수 사용은 피해야한다. 왜냐하면 this가 없으니까 호출한 객체를 가리키지 않고 전역 객체 window를 가리킨다.
const person = {
name: "Meerkat",
sayHi: () => console.log(`Hi ${this.name}`),
};
person.sayHi(); // Hi undefined
화살표 함수로 정의된 메소드를 prototype 객체로서 할당하는 경우도 위와 같이 동일한 문제가 발생한다.
const person = {
name: "Meerkat",
};
Object.prototype.sayHi = () => console.log(`Hi ${this.name}`);
person.sayHi(); // Hi undefined
생성자 함수는 prototype 프로퍼티를 가지며 prototype 프로퍼티가 가리키는 프로토타입 객체의 constructor를 사용한다. 하지만 화살표 함수는 prototype 프로퍼티를 가지고 있지 않기 때문에 사용하면 안된다.
const Foo = (name) => {
this.name = name;
};
// 화살표 함수는 prototype 프로퍼티가 없다
console.log(Foo.hasOwnProperty("prototype")); // false
const foo = new Foo("FFF"); // TypeError: Foo is not a constructor
addEventListener 함수는 이벤트가 발생할 때마다 콜백 함수를 호출하는데, 이때 콜백 함수의 this는 이벤트가 발생한 요소를 가리키게 된다.
<button>Click me!</button>
<script>
let button = document.querySelector('button');
button.addEventListener('click', function() {
console.log(this); // <button> 요소
});
</script>
<button>Click me!</button>
<script>
let button = document.querySelector('button');
button.addEventListener('click', () => {
console.log(this); // window 객체
});
</script>
this 키워드를 사용하지 않고, addEventListener 함수의 매개변수인 event 객체의 currentTarget 혹은 target 프로퍼티를 사용하여 이벤트가 발생한 요소에 접근하는 편이다.
<button>Click me!</button>
<script>
let button = document.querySelector('button');
button.addEventListener('click', (event) => {
console.log(event.target); // <button> 요소
});
</script>
보통 자바스크립트에서 this 키워드를 조작하는 대표적인 방법으로 call, apply, bind 함수를 이용한 기법이 있는데, 이는 this가 없는 화살표 함수에는 통하지 않는다.
const obj1 = { message: "Hello from obj1" };
const obj2 = { message: "Hello from obj2" };
// 일반 함수
function normalFunction() {
console.log(this.message);
}
// 화살표 함수
const arrowFunction = () => {
console.log(this.message);
};
// 일반 함수에서 this 변경
normalFunction.call(obj1); // 'Hello from obj1'
normalFunction.call(obj2); // 'Hello from obj2'
// 화살표 함수에서 this 변경 (변경이 되지 않음)
arrowFunction.call(obj1); // undefined
arrowFunction.call(obj2); // undefined
https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98-%EC%A0%95%EB%A6%AC#%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98_%ED%91%9C%ED%98%84
https://poiemaweb.com/es6-arrow-function