일급 객체

일급 객체의 조건

  1. 익명 리터럴을 런타임에 생성 가능

  2. 변수나 자료구조에 저장 가능

    //**변수**
    const foo = function() {
    	console.log("foo");
    }
    
    const bar = function() {
    	console.log("bar");
    }
    
    foo(); //foo
    bar(); //bar
    
    //**객체**
    const obj = { foo, bar };
    
    console.log(obj); //{ foo: [Function: foo], bar: [Function: bar] }
    
    //**배열**
    const arr = [foo, bar];
    console.log(arr[0]); //[Function: foo]
    
  3. 함수의 매개변수에 전달 가능

    function sayHello() {
       return "Hello, ";
    }
    function greeting(helloMessage, name) {
      console.log(helloMessage() + name);
    }
    // sayHello를 greeting 함수에 인자로 전달
    greeting(sayHello, "JavaScript!");
    
  4. 함수의 반환 값으로 사용 가능

    function sayHello() {
       return function() {
          console.log("Hello!");
       }
    }
    
//반환된 함수 다른 변수에 저장
const sayHello = function() {
	return function() {
		console.log("Hello!");
	}
}
const myFunc = sayHello();
myFunc();
//이중 괄호 사용
function sayHello() {
	return function() {
		console.log("Hello!");
	}
}
sayHello()();

함수 객체의 프로퍼티

function square(number) { return number * number; }

//square 함수의 프로퍼티 어트리뷰트 확인
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__는 함수의 프로퍼티가 아니라 Object.prototype 객체의 접근자 프로퍼티
console.log(Object.getOwnPropertyDescriptors(square, '__proto__')); // undefined


arguments 프로퍼티

function func1(a, b, c) {
    console.log(arguments[0]);
    console.log(arguments[1]);
    console.log(arguments[2]);
}
func1(1, 2, 3);
func1(1, 2);
func1(1, 2, 3, 4);