일급객체 조건
- 무명의 리터럴로 생성할 수 있다. → 런타임에 생성이 가능하다.
- 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.
- 함수의 매개변수에 전달할 수 있다.
- 함수의 반환값으로 사용할 수 있다.
// 1, 2 const plus = function (number) { return ++number; }; const minus = function (number) { return --number; }; // 2 const calculator = { plus, minus }; // 3, 4 function makeCalculator(calculator) { let number = 0; return function () { number = calculator(number); return number; }; } // 3 const increase = makeCalculator(calculator.plus); console.log(increase()); // 1 const decrease = makeCalculator(calculator.minus); console.log(decrease()); // -1
함수도 객체이기 때문에 프로퍼티를 가질 수 있고 함수의 모든 프로퍼티의 프로퍼티 어트리뷰트는 Object.getOwnPropertyDescriptors
메서드를 통해 알 수 있다.
function double(number) {
return number * 2;
}
console.log(Object.getOwnPropertyDescriptors(double));
/*
{
length: { value: 1, writable: false, enumerable: false, configurable: true },
name: { value: 'double', 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 }
} */
arguments 프로퍼티
함수 객체의 arguments
프로퍼티 값은 arguments
객체이고 이 객체는 함수 호출 시 전달된 인수들의 정보를 담고 있는 순회 가능한 유사 배열 객체이며 함수 내부에서 지역변수처럼 사용된다.
자바스크립트는 함수의 매개변수와 인수의 개수가 일치하는지 확인하지 않기 때문에 에러가 발생하지 않고 인수가 적을 경우 undefined
로 초기화된 상태를 유지하고 인수가 많을 경우 초과된 인수는 무시되는데 초과된 인수는 버려지지 않고 arguments
객체의 프로퍼티로 보관된다.
function plus(a, b) {
console.log(arguments);
return a + b;
}
console.log(plus()); // [Arguments] {} | NaN
console.log(plus(1)); // [Arguments] { '0': 1 } | NaN
console.log(plus(1, 2)); // [Arguments] { '0': 1, '1': 2 } | 3
console.log(plus(1, 2, 3)); // [Arguments] { '0': 1, '1': 2, '2': 3 } | 3
매개변수를 확정할 수 없는 가변 인자 함수 구현 시 유용하고 arguments
객체는 length
프로퍼티가 있는 유사 배열 객체이므로 for
문으로 순회할 수 있다.
function sum() {
let res = 0;
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
length 프로퍼티
함수를 정의할 때 선언한 매개변수의 개수
function noArg() {}
function oneArg(x) {
return x;
}
function twoArg(x, y) {
return x + y;
}
console.log(noArg.length); // 0
console.log(oneArg.length); // 1
console.log(twoArg.length); // 2
name 프로퍼티
함수 이름을 나타내는데 ES5와 ES6가 다르게 동작한다. 좀 더 자세히 설명하자면 익명함수 표현식의 경우 ES5는 빈 문자열 값으로, ES6는 함수 객체를 가리키는 식별자를 값으로 가진다.
var namedFunc = function foo() {};
var anonymousFunc = function () {};
function bar() {}
console.log(namedFunc.name); // 기명 함수 표현식: foo
console.log(anonymousFunc.name); // 익명 함수 표현식: anonymousFunc
console.log(bar.name); // 함수선언문: bar
proto 접근자 프로퍼티
모든 객체는 [[Prototype]]
이라는 내부 슬롯을 가지는데 [[Prototype]]
내부 슬롯은 객체지향 프로그래밍의 상속을 구현하는 프로토타입 객체를 가리킨다.
proto 프로퍼티는 [[Prototype]]
내부 슬롯이 가지는 프로토타입 객체에 간접적으로 접근하기 위해 사용하는 접근자 프로퍼티이다.
🪝 hasOwnProperty 메서드: 인수로 전달받은 프로퍼티 키가 객체 고유의 프로퍼티 키인 경우에만 true를 반환하고 상속받은 프로토타입의 프로퍼티 키인 경우 false를 반환한다.
const obj = { x: 1 };
console.log(obj.__proto__ === Object.prototype); // true
console.log(obj.hasOwnProperty('a')); // false
console.log(obj.hasOwnProperty('__proto')); // false
prototype 프로퍼티
생성자 함수로 호출할 수 있는 함수 객체, constructor만이 소유하는 프로퍼티이며 일반 객체와 생성자 함수로 호출할 수 없는 non-constructor에는 prototype 프로퍼티가 없다.
console.log(function () {}.hasOwnProperty('prototype')); // true
console.log({}.hasOwnProperty('prototype')); // false
→ 자바스크립트 개발자라면 알아야 할 33가지 개념 #20 자바스크립트: 순수함수
같은 입력값이 들어왔을 때, 항상 같은 출력이 나온다.
function double(number) {
return number * 2;
}
console.log(Math.random()); // 0.713656697021601
console.log(Math.random()); // 0.9997548358011055
console.log(double(2)); // 4
console.log(double(2)); // 4
double()
메소드는 같은 입력값이 들어왔을 때 항상 같은 출력값이 나온다. 하지만 Math.random()
은 0~1 사이의 새로운 랜덤 넘버를 생성하는데 이 함수는 순수하지 않다.
side-effect를 갖지 않는다.
순수 함수는 어떤 side-effect도 만들지 않는다. 쉽게 말하자면 어떤 외부 상태도 변환하지 않는다는 것을 의미한다.