인자를 입력받아 어떠한 연산을 수행한 후 결과값을 반환하는 재사용가능한 로직의 모음이다.
함수는 호출할 수 있는 값이다.
일급 객체(영어: first-class object)란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다. 보통 함수에 매개변수로 넘기기, 함수의 리턴값으로 반환하기, 변수에 대입하기와 같은 연산을 지원할 때 일급 객체라고 한다. 따라서 JS에서 함수는 일급 객체이다.
https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function
모든 함수는 객체이며 Function의 instance이다. 따라서 모든 함수는 Function.prototype의 메서드를 사용할 수 있습니다.
생성자 또는 메서드가 아닌 함수를 일반 함수라고 일반적으로 칭합니다.
일반 함수의 명명은 소문자로 시작하는 것이 관례입니다.
생성자 명명은 대문자로 시작하는 것이 관례입니다.
생성자는 new 연산자를 사용하여 호출하며, 생성자의 prototype을 프로토타입으로 하는 객체를 생성하는 역할을 수행합니다.
객체의 프로퍼티의 값이 함수인 프로퍼티를 메서드라고 합니다.
ES6에서는 메서드가 속한 객체를 내부 프로퍼티[[HomeObject]]
로 가진 함수가 메서드라고 공식적으로 정의하고 있습니다.
foo는 메서드이지만 bar는 메서드가 아닙니다. bar는 단지 값이 함수인 데이터 프로퍼티입니다.
const obj = {
foo() {
return "foo";
},
bar: function() {
return "bar";
}
}
※ 내장 프로토타입에 메서드를 추가할 일이 없어야 겠지만...
만약 내장 프로토타입에 메서드를 추가한다면 아래와 같이 프로퍼티를 정의하여야 합니다. 값을 할당하거나 value에 일반 함수로 정의한다면, 해당 함수에 [[Constructor]]
메서드가 존재하기 때문에 생성자로 사용될 수 있습니다.
Object.defineProperty(
Object.prototype,
"pio", // 메서드 명
{
value() { // ⛔ value: function() {
/* do what you want */
},
writable: true,
enumerable: false,
configurable: true
}
);
메서드 이름은 소문자로 시작하는 것이 관례입니다.
메서드는 this를 통해서 자신이 속한 객체를 참조합니다.
만약 메서드를 객체에서 추출하면, 객체와의 참조가 사라집니다. 따라서 추출된 메서드는 함수일 뿐 메서드가 아니며,
this는 strict mode에서는 undefined로, sloppy mode에서는 전역객체로 바뀝니다.
이러한 문제를 해결하기 위해서는 bind
를 사용하여 this값을 명시적으로 가지는 함수를 생성하여 추출하여야 합니다.
메서드와 화살표 함수는 생성자로 사용할 수 없습니다
new
연산자 사용 불가!)function
키워드를 항상 작성하여야 하는 반면 화살표 함수는 (parameter) => { /* block */ }
의 형태로 간결하게 작성할 수 있다. (parameter) => (/* value */)
와 같이 작성하면 (/* value */)
를 바로 반환하는 것으로 간주된다. this
, super
, arguments
, [new.target](http://new.target)
바인딩: 화살표 함수를 최근접에서 둘러싸고 있는 일반함수에 의해 정의됩니다.this
를 변경할 수 없음: 함수 내부의 this가 변경되지 않습니다. 즉, 선언 당시의 this 값으로 생명주기 내내 유지됩니다.[[Construct]]
메서드가 존재하지 않으므로 생성자로 사용할 수 없습니다. 또한 prototype
프로퍼티가 존재하지 않습니다.함수 선언은 새 변수를 선언하고 함수 객체를 만들어 그 변수에 할당하는 것입니다.
function foo() {
return 3;
}
함수 선언문은 완벽하게 호이스팅됩니다. 선언과 할당이 모두 스코프 최상단으로 끌어올려집니다.
함수 표현식은 값, 즉 함수 객체를 생성합니다.
// ES 5
var foo = function (a) {
return a + 3;
};
// ES 6+
const bar = (a) => a + 3;
함수 표현식은 부분적으로 호이스팅됩니다. 즉, 선언은 모두 스코프 최상단으로 끌어올려지지만, 할당은 끌어올려지지 않습니다. 따라서 함수 표현식으로 선언한 함수를 선언 이전에 접근하면 undefined가 반환되고, 이를 실행하면 에러가 발생합니다. undefined는 function이 아니므로 실행할 수 없기 때문입니다.
함수는 Function의 instance이기 때문에 Function 생성자를 이용하여 생성할 수 있습니다.
var foo = new Function("a", "b", "return a + b");
다만, 실제로 Function 생성자를 이용하여 함수를 생성하는 경우는 거의 없습니다.
함수를 호출하면 항상 this 가 묵시적 매개변수로 전달됩니다.
함수의 이름을 쓰고 괄호 안에 매개변수를 기재한다.
sloppy mode 에서 this는 전역 객체, strict mode에서 this는 항상 undefined 입니다.
foo(1,2);
생성자로서 사용하기 위해서는 new 연사자로 호출하여야 합니다. 생성자의 prototype 프로퍼티를 프로토타입으로 하는 객체가 생성되어 this로 전달됩니다.
new Foo();
객체를 통해 호출한다. 메서드를 호출한 객체(자신이 속한 객체)가 this로 전달됩니다. 이 this값을 메서드에서는 메서드 호출의 수신자(receiver)라고 부릅니다.
obj.method();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions
자바스크립트를 말하다: 15장 함수, 17장 객체와 상속