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


1.一級オブジェクト


次の条件を満たすオブジェクトを1レベルオブジェクトと呼びます.
1)無名の文字を生成できる.すなわち、実行時に生成することができる.
2)変数や資料構造(オブジェクト,配列など)に格納できる.
3)関数に渡すことができるパラメータ.
4)関数の戻り値として使用できます.
JavaScriptの関数は、次の例と上記の条件を満たすため、1レベルのオブジェクトです.
// 1) 무명의 리터럴로 생성할 수 있다.
// 2) 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.
// 런타임(할당 단계)에 함수 리터럴이 평가되어 함수 객체가 생성되고 변수에 할당된다.

const increase = function (num) {
  return ++num;
};

const decrease = function (num) {
  return --num;
};

// 2) 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.
const predicates = { increase, decrease };

// 3) 함수의 매개변수에 전달할 수 있다.
// 4) 함수의 반환값으로 사용할 수 있다.
function makeCounter(predicate) {
  let num = 0;
  
  return function () {
    num = predicate(num);
    return num;
  };
}

// 3. 함수는 매개변수에게 함수를 전달할 수 있다.
const increaser = makeCounter(predicates.increase);
console.log(increaser()); // 1
console.log(increaser()); // 2

const decreaser = makeCounter(predicates.decrease);
console.log(decreaser()); // -1
console.log(decreaser()); // -2
関数は1レベルのオブジェクトです.これは、オブジェクトと同じ関数を使用できることを意味します.オブジェクトが値であるため、関数は値に急いで等しくすることができます.
一級オブジェクトとして、関数が持つ特徴は普通のオブジェクトのように関数に伝達されるパラメータでも、関数の戻り値としても使用できます.これは関数式プログラミングを可能にするJavaScriptの利点の一つである.
関数は通常のオブジェクトと異なり、1つ目は呼び出すことができ、2つ目は関数自体を持つプログラムです.

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


関数はオブジェクトなので、propertyを持つこともできます.次はブラウザコンソールのconsoleです.dirメソッドを使用して、関数オブジェクトの内部を表示します.

オブジェクトは、squre関数内のすべてのPropertyのPropertyツリーです.getownPropertyDescriptorsメソッドで検証:
function square(number) {
    return number * number;
}

console.log(Object.getOwnPropertyDescriptors(square));
/*
{
  length: { value: 1, writable: false, enumerable: false, configurable: true },
  name: {
    value: 'square',
    writable: false,
    enumerable: false,
    configurable: true
  },
  arguments: {
    value: null,
    writable: false,
    enumerable: false,
    configurable: false
  },
  caller: {
    value: null,
    writable: false,
    enumerable: false,
    configurable: false
  },
  prototype: { value: {}, writable: true, enumerable: false, configurable: false }
}
*/
// __proto__는 square 함수의 프로퍼티가 아니다.
console.log(Object.getOwnPropertyDescriptors(square, '__proto__')); //undefined

// __proto__는 Object.prototype의 객체 접근자 프로퍼티다.
console.log(Object.getOwnPropertyDescriptors(Object.prototype, '__proto__'));
これらのパラメータ、呼び出し者、length、name、prototypeは、関数オブジェクトのデータpropertyです.これらのプロパティは、通常のオブジェクトにはない関数オブジェクトの固有のプロパティです.ただし、__proto__は、関数オブジェクト自体のPropertyではなく、アクセス者Propertyです.プロトタイプオブジェクトのpropertyを継承していることがわかります.

2-1)パラメータ構成


関数オブジェクトのarguments property値はargumentsオブジェクトです.Argumentsオブジェクトは、関数呼び出し時に伝達されるパラメータ情報を含むループ可能な類似配列オブジェクトであり、内部で領域変数として使用される.つまり、関数の外部で参照することはできません.

2-2)呼び出し元構成


関数オブジェクトの呼び出しプログラムとは、関数自体を呼び出す関数です.

2~3)長さの割合


関数オブジェクトのlength propertyとは、関数を定義するときに宣言されるパラメータの数です.

2-4)name property


関数オブジェクトのname propertyは関数名を表します.name propertyはES 6以前は非標準であり、ES 6では正式標準となっていた.

2-5) _._protoビジターProperty


.proto propertyは、[[prototype]内部スロットが指すprototypeオブジェクトにアクセスするためのアクセス者propertyです.内部スロットに直接アクセスすることはできません.間接アクセス方法が提供されている場合にのみアクセスできます.

2-6)原型製品


prototype propertyは、コンストラクション関数によって呼び出すことができるオブジェクトであり、コンストラクション関数のみが持つpropertyである.通常のオブジェクトとコンストラクション関数を呼び出すことができないnon-constructorには、プロトタイププログラムはありません.