ES6이전까지 JS의 함수는 별다른 구분 없이 다양한 목적으로 사용되었다.
⇒ 언뜻 보면 편리해 보일 수 있지만 실수를 유발 시킬 수 있으며 성능 면에서도 손해다!
// ES6 이전의 함수는 동일한 함수라도 다양한 형태로 호출할 수 있다.
var foo = function () {
return 1;
}
// 일반적인 함수로서 호출
foo(); // 1
// 생성자 함수로서 호출
new foo(); // foo {}
// 메서드로서 호출
var obj = { foo: foo };
obj.foo(); // 1
ES6 이전의 모든 함수는 일반 함수로서 호출할 수 있는 것은 물론 생성자 함수로서 호출할 수 있다. (ES6 이전의 모든 함수는 callable이면서 constructor다.)
var foo = function () {};
// ES6 이전의 모든 함수는 callable 이면서 constructor다.
foo(); // -> undefined
new foo(); // -> foo {}
주의할 것은 ES6 이전에 일반적으로 메서드라고 부르던 객체에 바인딩 된 함수도 callable이며 constructor라는 것이다.
// 프로퍼티 f에 바인딩 된 함수는 cllable이며 constructor다.
var obj = {
x: 10,
f: function () { return this.x; }
};
// 프로퍼티 f에 바인딩 된 함수를 메서드로서 호출
console.log(**obj.f()**); // 10
// 프로퍼티 f에 바인딩 된 함수를 일반 함수로서 호출
var bar = obj.f;
console.log(**bar()**); // undefined
// 프로퍼티 f에 바인딩 된 함수를 생성자 함수로서 호출
console.log(**new obj.f()**); // f {}
→ 객체에 바인딩 된 함수를 생성자 함수로 호출하는 것이 가능하다는 것은 문법 상&성능 상 문제가 있다!
함수에 전달되어 함수의 역할을 수행하는 콜백 함수도 마찬가지이다.
// 콜백 함수를 사용하는 고차 함수 map. 콜백 함수도 constructor이며
// 프로토타입을 생성한다.
[1, 2, 3].map(function (item) {
return item * 2;
}); // -> [ 2, 4, 6 ]