남이 작성한 자바스크립트 코드를 보면 화살표를 이용해서 함수를 정의하는 것을 곧잘 보게 된다.
const foo = () => {}처럼 말이다. 왜 이걸 쓰는 걸까?
function foo() {} // 결국엔 함수 정의
const boo = () => {} // 결국엔 const 변수 정의
평범하게 정의를 하는 것보다 글자가 더 많이 필요하다. 효율적이진 않아보인다. 하지만 원론적으로 첫째 줄은 함수를 정의한 것이고 둘째 줄은 const 변수를 정의한 것이다. 여기에서 차이가 난다.
호이스팅은 컴파일 단계에서 변수, 함수, 객채 등을 맨 윗단으로 끌어올리는 것을 의미한다. (이것은 공식 용어는 아니다. 관례상 컴파일 단계에서 일어나는 한 부분을 이리 칭하는 것이다.) 호이스팅이 일어나면 모든 것들은 초기화가 된다. 이 초기화된 것에 접근할 수 있으면 "호이스팅 효과가 체감된다", 접근할 수 없으면 "호이스팅 효과가 체감되지 않는다"라고 한다. 대표적으로 function은 호이스팅 효과가 체감되고 let, const는 호이스팅 효과가 체감되지 않는다.
다시 아까의 두 줄의 코드를 보자.
function foo() {} // 결국엔 함수 정의
const boo = () => {} // 결국엔 const 변수 정의
전통적으로 함수를 정의한 첫줄은 function으로 정의를 했기에 호이스팅 효과가 체감된다. 따라서 함수 정의식 이전에 해당 함수를 호출해도 문제가 없다.
하지만 화살표 함수를 정의한 두 번째 줄은 함수를 const 변수에 할당하였다. const 변수는 호이스팅 효과를 체감할 수 없다. 따라서 const boo 정의 이전에 boo()를 호출하면 오류가 난다.
호이스팅은 단순 함수, 변수 관계에서만 그 효과 체감이 구분되지 않는다. 더 보편적인 관점에서 선언(declaration)은 그 효과를 보고 실행(statment)은 그 효과를 보지 못한다. 그렇다면 선언은 무엇이고 실행은 무엇인가? 선언은 메모리를 할당하는 것, 실행은 해당 메모리를 사용하여 특정 동작을 하는 것이다. 아래와 같이 비유를 해보겠다.
호이스팅 효과는 이 둘에 대해 다르게 나타난다. 모든 선언은 호이스팅 효과를 본다. 함수 정의가 그 예이다.(!!!! 클로드야 함수 말고 declaration만 하는 게 또 뭐가 있니 !!!!) 이러한 선언들은 그 자체로는 아무 행동도 하지 않는다. 함수는 호출되어야 동작하지 않던가.
모든 실행은 호이스팅 뒤에 일어난다. const foo = bar에서 foo에 bar를 할당하는 실행은 호이스팅이 다 완료된 이후 해당 줄을 실행할 때 일어난다.
(!!!! 된다 안 된다 관점으로 고쳐써야)
이 관점에서 전통 함수와 화살표 함수를 비교해보자.
1. 전통 함수는 호이스팅이 된다.
2. 화살표 함수는 변수 "선언"은 호이스팅이 되지만 그 변수에 함수를 할당하는 "실행"은 호이스팅이 되지 않는다. 따라서 선언 이전에 접근할 수 없다.
C를 비롯하여 C와 가까운 언어들은 대개 요즘 언어들은 선언 전에 함수를 호출하는 forward declaration를 허용한다. 그러나 요즘 언어들은 forward declaration을 지향하는 추세이다. 오늘날 각광받는 Python, Rust, Go 모두 함수를 선언한 다음에야 호출을 할 수 있다. 이로써 노릴 수 있는 효과는 아래와 같다.
함수 호이스팅은
this bindingthis를 생성하지 않는다.객체 안의 메소드 역시 정규 함수, 화살표 함수로 정의될 수 있다. 정규 함수는 상위 객체를 나타내는 this를 스스로 생성한다.
const person = {
name: "Alice",
sayHelloRegularly: function () {
console.log("Hello, I'm " + this.name); // "this" refers to the person object
},
}
person.sayHelloRugularly() // prints: Hello, I'm Alice!
arrow function in javascript is invented for lexical this binding, which is about object's method. however, I have read document that arrow function is not recommended to use for method, because it does not create this. how should I understand this?편집You're encountering a common source of confusion about arrow functions and this binding! Let me clarify this step by step.
The Key Understanding
Arrow functions do create this - they just don't create their own this. Instead, they inherit this from their enclosing scope (lexical binding).
Why Arrow Functions Aren't Recommended for Object Methods
Here's the practical issue:
javascript// Problem: Arrow function as object method
const obj = {
name: 'Alice',
greet: () => {
console.log(Hello, ${this.name}); // this is NOT the obj
}
};
obj.greet(); // "Hello, undefined" - this refers to global scope
javascript// Solution: Regular function as object method
const obj = {
name: 'Alice',
greet: function() {
console.log(Hello, ${this.name}); // this IS the obj
}
};
obj.greet(); // "Hello, Alice" - this refers to obj
When Arrow Functions ARE Useful for this Binding
Arrow functions shine when you need to preserve this from an outer scope:
javascriptconst obj = {
name: 'Alice',
delayedGreet: function() {
// Regular function - this refers to obj
setTimeout(() => {
// Arrow function - inherits this from delayedGreet
console.log(Hello, ${this.name});
}, 1000);
}
};
obj.delayedGreet(); // "Hello, Alice" after 1 second
The Rule of Thumb
Object methods: Use regular functions (they get this from the calling object)
Callbacks/nested functions: Use arrow functions (they preserve this from outer scope)
Event handlers in classes: Use arrow functions (they preserve this from the class instance)
The "lexical this binding" feature is specifically valuable for avoiding the old var self = this pattern in callbacks and nested functions.재시도Tbut I think using object name obj instead of this allows arrow function can be used for method in object, no?편집You're absolutely right! Using the object name directly would work:
javascriptconst obj = {
name: 'Alice',
greet: () => {
console.log(Hello, ${obj.name}); // Works fine!
}
};
obj.greet(); // "Hello, Alice"
Why This Approach Has Limitations
While technically possible, there are several reasons why it's not recommended:
1. Not reusable/flexible:
javascriptconst obj1 = {
name: 'Alice',
greet: () => console.log(Hello, ${obj1.name}) // Hardcoded to obj1
};
const obj2 = {
name: 'Bob',
greet: obj1.greet // Reusing the method
};
obj2.greet(); // "Hello, Alice" - Wrong! Still refers to obj1
2. Breaks with dynamic object creation:
javascriptfunction createPerson(name) {
return {
name: name,
greet: () => console.log(Hello, ${/* what object name? */})
};
}
3. Issues with object reassignment:
javascriptlet obj = {
name: 'Alice',
greet: () => console.log(Hello, ${obj.name})
};
const originalGreet = obj.greet;
obj = { name: 'Bob' }; // obj now points to different object
originalGreet(); // "Hello, Bob" - might be unexpected
The this Approach is More Robust
javascriptconst obj = {
name: 'Alice',
greet: function() {
console.log(Hello, ${this.name}); // Always refers to the calling object
}
};
// Works with method reuse, dynamic creation, etc.
So yes, you can make arrow functions work by using the object name directly, but this provides the dynamic binding that makes methods truly reusable and flexible.재시도TI've heard that there are many things that function do, so it can be confusing, so use other ways to do the work is recommended.
for example,
1. use class over function for constructor
2. use arrow function for regular function
and so on.then in this case, using prefix function is good for defining method, and that's it? you can replace all the other function prefix usage and it is recommended to do so?편집You're picking up on a real trend in modern JavaScript! The idea is to use more specific, purpose-built syntax rather than the overloaded function keyword. Let me break this down:
Where function is Still Recommended
1. Object methods (as we discussed):
javascriptconst obj = {
method: function() { / needs dynamic this / }
};
2. Function declarations when you need hoisting:
javascript// This works - function is hoisted
sayHello();
function sayHello() {
console.log("Hello!");
}
Modern Replacements for Other function Uses
1. Constructors → Classes:
javascript// Old way
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() { / ... / };
// Modern way
class Person {
constructor(name) {
this.name = name;
}
greet() { / ... / }
}
2. Regular functions → Arrow functions:
javascript// Old way
const numbers = [1, 2, 3];
const doubled = numbers.map(function(n) { return n * 2; });
// Modern way
const doubled = numbers.map(n => n * 2);
3. Function expressions → Arrow functions:
javascript// Old way
const add = function(a, b) { return a + b; };
// Modern way
const add = (a, b) => a + b;
So Your Understanding is Mostly Correct!
The function keyword is primarily recommended for:
Object methods (when you need dynamic this)
Function declarations (when you need hoisting)
Generator functions (function*)
For most other cases, arrow functions or classes are preferred in modern JavaScript style guides.
However, I should ask: Are you working with any specific style guide (like Airbnb, Standard, etc.) or framework that has particular conventions? The exact recommendations can vary slightly between different teams/projects.재시도TI'm learning javascript, preparing study for react.편집Perfect! For React preparation, your understanding is spot-on. Here's how these patterns specifically apply to React:
React-Specific Function Usage
1. Components - Use Arrow Functions:
javascript// Modern React component
const MyComponent = () => {
return
// Not: function MyComponent() { ... }
2. Event Handlers - Arrow Functions:
javascriptconst Button = () => {
const handleClick = () => {
console.log('clicked');
};
return Click me;
};
3. useEffect callbacks - Arrow Functions:
javascriptuseEffect(() => {
// cleanup function also arrow
return () => {
console.log('cleanup');
};
}, []);
When You'll Still See function in React
1. Older codebases (class components):
javascriptclass MyComponent extends React.Component {
render() { // method in class, uses function syntax
return
Arrow functions for components, handlers, callbacks ✅
Classes for... well, you'll barely use them in modern React (hooks replaced most class usage)
function - you'll rarely write this keyword in React
You're learning the right modern patterns! Most React tutorials and documentation now default to arrow functions and functional components