developer tip

명명 된 함수 식을 사용하는 이유는 무엇입니까?

optionbox 2020. 9. 8. 07:54
반응형

명명 된 함수 식을 사용하는 이유는 무엇입니까?


JavaScript에서 함수 표현을 수행하는 두 가지 방법이 있습니다.

명명 된 함수 식 (NFE) :

var boo = function boo () {
  alert(1);
};

익명 함수 표현식 :

var boo = function () {
  alert(1);
};

그리고 둘 다 boo();. 익명 함수를 사용해야하는 이유 /시기와 명명 된 함수 표현식을 사용해야하는시기를 알 수 없습니다. 그들 사이에는 어떤 차이가 있습니까?


익명 함수 표현식의 경우 함수는 익명입니다  . 말 그대로 이름이 없습니다. 할당하려는 변수에는 이름이 있지만 함수에는 없습니다. (업데이트 : 그것은 ES5를 통해 사실이었습니다. ES2015 [일명 ES6]부터, 종종 익명의 표현으로 생성 된 함수는 실제 이름을 얻습니다 [그러나 자동 식별자는 아닙니다], 계속 읽으십시오 ...)

이름이 유용합니다. 이름은 스택 추적, 호출 스택, 중단 점 목록 등에서 볼 수 있습니다. Names are a Good Thing ™.

(이전 버전의 IE [IE8 이하]에서 명명 된 함수 표현식을주의해야했습니다. 두 개의 완전히 별개의 함수 객체를 완전히 다른 시간에 실수로 만들었 기 때문입니다 [더 자세한 내용은 내 블로그 기사 Double take ]. IE8 [!!] 지원, 익명 함수 표현식 또는 함수 선언 을 고수하는 것이 가장 좋지만 이름이 지정된 함수 표현식은 피하십시오.)

명명 된 함수 표현식에 대한 한 가지 중요한 점은 함수 본문 내에서 해당 함수 이름으로 범위 내 식별자를 생성한다는 것입니다.

var x = function example() {
    console.log(typeof example); // "function"
};
x();
console.log(typeof example);     // "undefined"

하지만 ES2015에서 많은 "익명"함수 표현식은 이름이있는 함수를 생성하며, 이는 컨텍스트에서 이름을 추론하는 데 매우 똑똑한 다양한 최신 JavaScript 엔진에 의해 선행되었습니다. ES2015에서 익명 함수 표현식은 이름이 boo. 그러나 ES2015 + 의미 체계를 사용하더라도 자동 식별자는 생성되지 않습니다.

var obj = {
    x: function() {
       console.log(typeof x);   // "undefined"
       console.log(obj.x.name); // "x"
    },
    y: function y() {
       console.log(typeof y);   // "function"
       console.log(obj.y.name); // "y"
    }
};
obj.x();
obj.y();

함수 이름에 대한 할당 은 사양의 다양한 작업에 사용되는 SetFunctionName 추상 작업으로 수행됩니다.

짧은 버전은 기본적으로 다음과 같이 할당 또는 초기화와 같은 항목의 오른쪽에 익명 함수 표현식이 나타날 때마다 발생합니다.

var boo = function() { /*...*/ };

(또는 때문일 수 있습니다 let또는 const보다는 var) , 또는

var obj = {
    boo: function() { /*...*/ }
};

또는

doSomething({
    boo: function() { /*...*/ }
});

(those last two are really the same thing), the resulting function will have a name (boo, in the examples).

There's an important, and intentional, exception: Assigning to a property on an existing object:

obj.boo = function() { /*...*/ }; // <== Does not get a name

This was because of information leak concerns raised when the new feature was going through the process of being added; details in my answer to another question here.


Naming functions is useful if they need to reference themselves (e.g. for recursive calls). Indeed, if you are passing a literal function expression as an argument directly to another function, that function expression cannot directly reference itself in ES5 strict mode unless it is named.

For example, consider this code:

setTimeout(function sayMoo() {
    alert('MOO');
    setTimeout(sayMoo, 1000);
}, 1000);

It would be impossible to write this code quite this cleanly if the function expression passed to setTimeout were anonymous; we would need to assign it to a variable instead prior to the setTimeout call. This way, with a named function expression, is slightly shorter and neater.

It was historically possible to write code like this even using an anonymous function expression, by exploiting arguments.callee...

setTimeout(function () {
    alert('MOO');
    setTimeout(arguments.callee, 1000);
}, 1000);

... but arguments.callee is deprecated, and is outright forbidden in ES5 strict mode. Hence MDN advises:

Avoid using arguments.callee() by either giving function expressions a name or use a function declaration where a function must call itself.

(emphasis mine)


If a function is specified as a Function Expression, it can be given a name.

It will only be available inside the function (except IE8-).

var f = function sayHi(name) {
  alert( sayHi ); // Inside the function you can see the function code
};

alert( sayHi ); // (Error: undefined variable 'sayHi')

This name is intended for a reliable recursive function call, even if it is written to another variable.

In addition, the NFE (Named Function Expression) name CAN be overwritten with the Object.defineProperty(...) method as follows:

var test = function sayHi(name) {
  Object.defineProperty(test, 'name', { value: 'foo', configurable: true });
  alert( test.name ); // foo
};

test();

Note: that with the Function Declaration this can not be done. This "special" internal function name is specified only in the Function Expression syntax.


You should always use named function expressions, that's why:

  1. You can use the name of that function when you need recursion.

  2. Anonymous functions doesn't help when debugging as you can't see the name of the function that causes problems.

  3. When you do not name a function, later on its harder to understand what it's doing. Giving it a name makes it easier to understand.

var foo = function bar() {
    //some code...
};

foo();
bar(); // Error!

Here, for example, because the name bar is used within a function expression, it doesn't get declared in the outer scope. With named function expressions, the name of the function expression is enclosed within its own scope.


Using named function expressions is better, when you want to be able to reference the function in question without having to rely on deprecated features such as arguments.callee.

참고URL : https://stackoverflow.com/questions/15336347/why-use-named-function-expressions

반응형