オブジェクトとしての関数とシンボル関数の式


JavaScriptでは、関数は値として扱われます.
すべての値にはデータ型があり、関数のデータ型はオブジェクトです.
関数は、呼び出し可能な動作オブジェクトです.関数を呼び出すだけでなく、オブジェクトのように関数にpropertyを追加、削除、または参照によって渡すこともできます.

Property“name”


関数オブジェクトにはいくつかのpropertyがあります.
「name」propertyを使用して、関数名を取得します.
function sayHi() {
  alert("Hi");
}

alert(sayHi.name); // sayHi
関数オブジェクトに名前を割り当てるロジックは、匿名関数でも自動的に名前が割り当てられます.
let sayHi = function() {
  alert("Hi");
};

alert(sayHi.name); // sayHi (익명 함수이지만 이름이 있네요!)
デフォルト値を使用して名前を指定する場合も同様です.
function f(sayHi = function() {}) {
  alert(sayHi.name); // sayHi (이름이 있네요!)
}

f();
JavaScriptリストで定義されているこの機能を「コンテキスト名」と呼びます.関数の名前を指定しない場合は、コンテキストから名前が取得されます.
オブジェクトメソッドの名前は、「name」プロパティを使用してインポートすることもできます.
let user = {

  sayHi() {
    // ...
  },

  sayBye: function() {
    // ...
  }

}

alert(user.sayHi.name); // sayHi
alert(user.sayBye.name); // sayBye
ただし,オブジェクトメソッド名は関数のように自動的に割り当てられるわけではない.場合によっては、適切な名前を推定できない場合があります.この場合、name property enving文字列が格納されます.
// 배열 안에서 함수를 생성함
let arr = [function() {}];

alert( arr[0].name ); // <빈 문자열>
// 엔진이 이름을 설정할 수 없어서 name 프로퍼티의 값이 빈 문자열이 됨
実際の作業では、ほとんどの関数に名前が付いているため、このような状況は起こり得ません.

長さパーセント


組み込みプログラムlengthは、関数パラメータの個数を返す.
function f1(a) {}
function f2(a, b) {}
function many(a, b, ...more) {}

alert(f1.length); // 1
alert(f2.length); // 2
alert(many.length); // 2
上記の例では、残りのパラメータが個数に含まれていないと判断できます.
一方、length propertyは、他の関数で実行される関数タイプをチェックするためにもよく使用されます.
次に、質問に使用されるquestionと、質問の答えに従って任意の数のhandler関数を受信するaskとを見てみましょう.
ユーザが回答を提出すると、askはHandler関数を呼び出す.2つのHandler関数をaskに渡すことができます.
パラメータ
  • の関数はなく、ユーザがOKをクリックしたときのみ
  • が呼び出される.
  • パラメータを持つ関数は、ユーザーがOKをクリックしてもCancelをクリックしても呼び出されます.
    その後、handler.length propertyを使用して、状況に適合するhandlerを呼び出すことができる.
  • ユーザーが肯定的な回答をするときにパラメータが使用できないハンドルを作成するか、ユーザーの応答タイプにかかわらず、汎用的なハンドルを構築することができます.  ask  内部から  handler.lengthと一緒に使えばいいです.
    引数の種類によって,引数を扱う方式をプログラミング言語で多形性と呼ぶ.JavaScriptライブラリを見ると、多形性があちこちで使われていることがわかります.

    カスタム価格


    独自に作成したpropertyを関数に追加することもできます.
    これらの特徴を用いて,関数呼び出しの回数をcounter propertyに保存した.
    function sayHi() {
      alert("Hi");
    
      // 함수를 몇 번 호출했는지 세봅시다.
      sayHi.counter++;
    }
    sayHi.counter = 0; // 초깃값
    
    sayHi(); // Hi
    sayHi(); // Hi
    
    alert( `호출 횟수: ${sayHi.counter}` ); // 호출 횟수: 2회

    💡 番組は変数ではありません。

    sayHi.counter = 0に示すように、関数にプロパティが割り当てられている場合は、関数に領域変数を指定します.  counterは生産できません.  counter  プロパティと変数  let counterは全く関係ありません.
    Propertyを保存するように、関数をオブジェクトとして扱うことができますが、実行には影響しません.変数は関数propertyではないので、関数propertyは変数ではありません.両者の間には共通点がない.
    モジュールは関数プログラムで代用できます.関数propertyを使用してcounter関数を置き換えます.
    function makeCounter() {
    
      // let count = 0 대신 아래 메서드(프로퍼티)를 사용함
    
      function counter() {
        return counter.count++;
      };
    
      counter.count = 0;
    
      return counter;
    }
    
    let counter = makeCounter();
    alert( counter() ); // 0
    alert( counter() ); // 1
    countは、外部ディレクトリ環境ではなく、関数propertyに格納されます.
    2つの方法の違いは、count値が外部変数に格納されることである.エンクロージャを使用している場合は、外部コードからcountにアクセスできません.countの値は、オーバーラップ関数内でのみ変更できます.逆に、関数propertyを使用してcountを関数にバインドする場合は、次の例に示すように、外部で値を変更できます.

    記名関数式


    シンボル関数式(Named Function Expression,NFE)は、名前付き関数式を表す用語です.
    一般的な関数式を見てみましょう.
    let sayHi = function(who) {
      alert(`Hello, ${who}`);
    };
    ここに名前をつけましょう.
    let sayHi = function func(who) {
      alert(`Hello, ${who}`);
    };
    「func」という名前は、関数式のままです.式は指定した形式を保持するため、関数宣言には変更されません.名前を追加しても、既存の機能が機能しないことはありません.
    sayhi()で呼び出すこともできます.
    let sayHi = function func(who) {
      alert(`Hello, ${who}`);
    };
    
    sayHi("John"); // Hello, John
    funcという名前をつけると2つの変化があります.
  • 名を使用して、関数式の内部で自己を参照できます.
  • 記名関数式以外の名前は使用できません.
  • n.関数  sayHiを例にこれについて検討した.n.関数  sayHi  whoに値がない場合は、引数です.  ”Guest”を受け取って自分を呼ぶ.
    let sayHi = function func(who) {
      if (who) {
        alert(`Hello, ${who}`);
      } else {
        func("Guest"); // func를 사용해서 자신을 호출합니다.
      }
    };
    
    sayHi(); // Hello, Guest
    
    // 하지만 아래와 같이 func를 호출하는 건 불가능합니다.
    func(); // Error, func is not defined (기명 함수 표현식 밖에서는 그 이름에 접근할 수 없습니다.)
    例:
    let sayHi = function(who) {
      if (who) {
        alert(`Hello, ${who}`);
      } else {
        sayHi("Guest");
      }
    };
    ただし、このようにコードを記述すると、外部コードがsayHiに変更される可能性があります.新しい変数に関数式を割り当て、既存の変数にnullを割り当てるとエラーが発生します.
    let sayHi = function(who) {
      if (who) {
        alert(`Hello, ${who}`);
      } else {
        sayHi("Guest"); // TypeError: sayHi is not a function
      }
    };
    
    let welcome = sayHi;
    sayHi = null;
    
    welcome(); // 중첩 sayHi 호출은 더 이상 불가능합니다!
    エラーは、関数がsayHiを自分の外部集合環境からインポートしたことによるものです.地域(local)Lexical環境にはsayHiがないため、外部Lexical環境ではsayHiを検索し、関数呼び出し時に外部Lexical環境のsayHinull円が格納されたためエラーが発生した.
    関数式に名前を付けると、この問題を解決できます.
    let sayHi = function func(who) {
      if (who) {
        alert(`Hello, ${who}`);
      } else {
        func("Guest"); // 원하는 값이 제대로 출력됩니다.
      }
    };
    
    let welcome = sayHi;
    sayHi = null;
    
    welcome(); // Hello, Guest (중첩 호출이 제대로 동작함)
    「func」の名前は関数領域レベル(function-local)に存在するため、外部コレクション環境で検索する必要はありません.外部の電子環境では見えない.関数式の名前は、リストで現在の関数のみを参照するように定義されているためです.
    このように、記名関数式を使用すると、sayHiまたはwelcomeのような外部変数がどのように変化しても、funcという名前の「内部関数名」を使用して、関数式の内部でいつでも自分を呼び出すことができます.
    関連項目:https://ko.javascript.info/function-object