JavaScript)関数と一級オブジェクト


関数と一級オブジェクト


1.一級オブジェクト


👀 一級オブジェクト?
  • 無名の文字を生成できます.(実行時に作成可能)
  • 変数またはデータ構造(オブジェクト、配列)に格納できます.
  • 関数のパラメータに渡すことができます.
  • 関数の戻り値として使用できます.
  • JavaScriptの関数は上記の条件を満たすため、1レベルのオブジェクトです.
    関数は1レベルのオブジェクトです.これは、関数がオブジェクトと同じように使用できることを意味します.オブジェクトが値であるため、関数は値と同じ値と見なすことができます.したがって、関数をテキストとして定義し、実行時に関数オブジェクトとして評価することができます.
    関数はオブジェクトですが、通常のオブジェクトとは異なります.通常のオブジェクトは呼び出せませんが、関数オブジェクトを呼び出すことができます.また,関数オブジェクトは,通常のオブジェクトにはない関数自体のpropertyを持つ.

    2.関数オブジェクトの構成


    関数はオブジェクトです.したがって、関数はpropertyを有することもできる.
    function square(number) {
    	return number * number;
    }
    
    console.dir(square);

    square関数のObject.getOwnPropertyDescriptors法により検証したところ,パラメータ,呼び出し者,length,name,プロトタイプpropertyはいずれも関数オブジェクトのデータpropertyであることが分かった.これらのプロパティは、通常のオブジェクトにはない関数オブジェクトの固有のプロパティです.

    2-1. パラメータ構成


    関数オブジェクトのarguments property値はargumentsオブジェクトです.Argumentsオブジェクトは、関数呼び出し時に伝達されるパラメータ情報を含むループ可能な類似配列オブジェクトであり、関数では領域変数として使用される.(関数の外部参照はできません.)
    関数オブジェクトのarguments propertiesは現在、一部のブラウザでサポートされていますが、ES 3から標準で廃止されています.
    JavaScript関数のパラメータが引数の個数と一致するかどうかはチェックしません.したがって,関数呼び出し時にパラメータ数をパラメータ数で渡さなくてもエラーは発生しない.
    関数を定義するときに宣言されるパラメータの関数内での処理方法は変数と同じです.すなわち、関数が呼び出されると、パラメータは関数内で暗黙的に宣言され、未定義に初期化され、引数が割り当てられる.
    伝達されたパラメータが宣言されたパラメータの数より少ない場合、未伝達パラメータは未定義の初期化状態を維持し、伝達されたパラメータがより多い場合、スキップされたパラメータは無視されます.
    ただし、それ以上のパラメータが破棄されるという意味ではなく、すべてのパラメータがパラメータオブジェクトのデフォルト値として保存されます.
    Argumentsオブジェクトは、パラメータ個数を決定できない可変パラメータ関数を実装する場合に便利です.
    function sum() {
    	let res = 0;
      
      	// argumnts 객체는 length 프로퍼티가 있는 유사 배열 객체이므로 for문으로 순회할 수 있다.
      	for (let i = 0; i < arguments.length; i++) {
        	res += arguments[i];
        }
      
      	return res;
    }
    
    console.log(sum()); // 0
    console.log(sum(1, 2)); // 3
    console.log(sum(1, 2, 3)); // 6
    Argumentsオブジェクトにはパラメータ情報が配列形式で含まれていますが、実際の配列ではなく、類似の配列オブジェクトです.アレイのようなオブジェクトはアレイではないため、アレイメソッドを使用するとエラーが発生します.
    これらの問題を解決するために,ES 6はRestパラメータを導入した.
    function sum(...args) {
    	return args.reduce((pre, cur) => pre + cur, 0);
    }
    
    console.log(sum(1, 2)); // 3
    console.log(sum(1, 2, 3, 4, 5)); // 15

    2-2. 長さパーセント


    length propertyとは、関数を定義するときに宣言されるパラメータの数です.
    function foo() {}
    console.log(foo.length); // 0
    
    function bar(x) {
    	return x;  
    }
    console.log(bar.length); // 1
    
    function baz(x, y) {
    	return x + y;  
    }
    console.log(baz.length); // 2
    なお、argumentsオブジェクトのlength propertyと関数オブジェクトのlength propertyの値は異なる場合があります.

    2-3. 名義財産


    関数オブジェクトのname propertyは関数名を表します.name propertyはES 5以前は非標準であり、ES 6では正式標準となっていた.ES 5とES 6ではname propertyの動作が異なることに注意してください.

    2-4. __protoビジターProperty


    すべてのオブジェクトに[Prototype]という内部スロットがあります.[prototype]内部スロットとは、オブジェクト向けのプログラミング継承を実現するプロトコルタイプのオブジェクトです.__proto__ propertyは、[Prototype]の内部スロットが指すPrototypeオブジェクトにアクセスするためのアクセス者propertyです.内部スロットに直接アクセスすることはできません.間接アクセス方法が提供されている場合にのみアクセスできます.
    const obj = { a: 1 };
    
    // 객체 리터럴 방식으로 생성한 객체의 프로토타입 객체는 Object.prototype 이다.
    console.log(obj.__proto__ === Object.prototype); // true;

    2-5. プロトタイプスキーム


    prototype propertyは、コンストラクション関数によって呼び出すことができる関数オブジェクト、すなわちコンストラクション関数のみが持つpropertyです.通常のオブジェクトとコンストラクション関数で呼び出せないnon-constructorにはprototype propertyはありません.
    prototype propertyとは、関数がオブジェクトを作成するコンストラクション関数として呼び出されると、コンストラクション関数が作成するインスタンスのプロトタイプオブジェクトを指します.
    モダンJavaScript Deep Diveを読んでまとめた文章.😊