이번 장은 함수에 대한 내용이다. 가장 중요하게 생각해도 되는 장이다. 함수형 자바스크립트에 대한 책도 많이 나와 있다. (추후에는 함수형 자바스크립트 입문 책도 샀으니 관련하여 정리할 예정이지만, 이 장은 자바스크립트 핵심 가이드에서 나온 내용을 주로 정리한다)
함수는 모듈화의 근간, 코드의 재사용성, 정보의 구성 및 은닉 등에 사용, 객체의 행위를 지정하는데도 사용할 수 있음.
함수 객체
자바스크립트에서 함수는 객체임. 객체는 프로토타입 객체로 숨겨진 연결을 갖는 이름/값 쌍들을 집합체로 객체 중에서 객체 리터럴로 생성되는 객체는 Object.prototype에 연결됨. 반면 함수 객체는 Function.prototype에 연결됨(다시 Function은 Object.prototype에 연결됨)
- 모든 함수는 숨겨진 두 개의 추가적인 속성이 있음(함수의 문맥(Context)과 함수 행위를 구현하는 코드(code)임)
- 함수는 변수나 객체, 배열등에 저장, 다른 함수에 전달되는 인수로도 사용, 함수의 반환 값으로도 사용함
함수 리터럴
- 함수 객체는 함수 리터럴로 생성할 수 있음
- 함수 리터럴에는 네가지 부분이 있음
- 함수 리터럴로 생성한 함수 객체는 외부 문맥으로의 연결이 있음 → 클로저라고 함
함수를 정의하는 방법(모던 자바스크립트 입문 책 참고)
// 함수 선언문으로 정의하는 방법
function square(x) { return x * x; }
// 함수 리터럴로 정의하는 방법
var square = function(x) { return x*x; }
// Function 생성자로 정의하는 방법
var square = new Function(“x”, “return x*x”; }
// 화살표 함수 표현식으로 정의하는 방법 (ECMAScript 6부터 추가된 형태)
var square = x => x*x;
호출
- 함수를 호출하면 현재 함수의 실행을 잠시 중단하고 제어를 매개변수와 함께 호출한 함수로 넘김(콜백 지옥... 이 생기는 원리)
- 모든 함수는 명시되어 있는 매개 변수에 더해서 this라는 매개변수는 객체 지향 프로그래밍 관점에서 매우 중요함(함수형 프로그래밍인 동시에 객체 지향형 프로그래밍임)
- 매개변수는 호출하는 패턴에 의해 결정됨
- 메소드 호출 패턴: 함수를 객체의 속성에 저장하는 경우
- 함수 호출 패턴: 함수가 객체의 속성이 아닌 경우에는 함수로 호출
- 생성자 호출 패턴: 프로토타입에 의해서 상속이 이루어지는 언어로, 객체가 자신의 속성들을 다른 객체에 바로 상속할 수 있다는 뜻 → new로 생성하면 this에 바로 바인딩됨
- apply 호출 패턴: apply 메서드는 함수를 호출할 때 사용할 인수들의 배열을 받아들여서 this값을 선택할 수 있도록 해줌.
인수 배열(arguments)
추가적인 매개변수로 arguments라는 배열을 사용할 수 있음. 이 배열은 함수를 호출할 때 전달된 모든 인수를 접근할 수 있게 함(하지만 유용한 패턴은 아니라고 하니 조심하자)
var sum = function( ) {
var i , sum. = 0 ;
for(i = 0 ; i < arguments.length; i+=1) {
sum += arugments[i];
}
return sum;
}
document.writeln(sum(4,8,15,16,23,42)); // 108
반환(return)
- return 문은 함수가 끝에 도달하기 전에 제어를 반환할 수 있음
- 반환값이 지정되지 않으면 undefined가 반환됨
예외
- 예외는 정상적인 프로그램의 흐름을 방해하는 비정상적인 사고임
- 예외 객체는 try문의 catch절에 전달됨
var try_it = function( ) {
try {
add("seven");
} catch(e) {
// add를 잘못 호출하면 여기로 들어오므로 여기서 처리하자
document.writeln(e.name + ": " + e.message);
}
}
try_it() ;
기본 타입에 기능 추가
언어의 기본 타입에 기능을 추가할 수 있음(강력한 기능이다)
예를 들어 다음과 같이 method라는 메소드를 Function.prototype에 추가하면서 이후 모든 함수에서 이 메서드를 사용할 수 있음
Function.prototype.method = function(name, func) {
this.prototype[name] = func;
return this;
};
자바스크립트에는 문자열의 양 끝에 있는 빈칸을 지우는 메소드가 없는 경우에도 다음과 같이 정의해서 사용하면 된다고(오호 +ㅂ+)
String.method('trim', function(){
return this.replace(/^\s+|\s+$/g, '');
});
document.writeln('"' + " neat ".trim() +'"');
재귀적 호출
유효범위(Scope)
ECMAScript 6부터 let을 사용하여 지역으로 유효 범위를 제한할 수 있다 { let xx } 범위임
for(let i =0 ; i < elm.length ;i++){
//let 유효 범위임
elm[i].onclick = function(){
console.log(i);
}
// end of let scope
}
클로저(Closure)
- 내부 함수에서 자신을 포함하고 있는 외부 함수의 매개변수와 변수들을 접근할 수 있다
<변수에 접근하지 못하는 예>
var myObject = function() {
var value = 0;
return {
increment : function(inc) {
value += typeof inc === 'number'? inc : 1;
}, getValue : function( ) {
return value;
}
};
}();
<get_status메서드가 있는 객체를 반환 -> 객체에 대한 참조를 myQuo에 저장 -> 이미 반환된 뒤에도 quo의 status에 접근할 수 있음 >
var quo = function(status){
return {
get_status : function(){
return status ;
}
};
};
var myQuo = quo("amazed"); // myQuo에 저장함
document.writeln(myQuo.get_status()); // myQuo를 통하여 status를 접근할 수 있음
(추가적으로 업데이트 하겠다. 오늘은 여기까지만)
콜백(Callback)
- 비연속적인 이벤트를 다루는 것에 대해서 쉽게 할 수 있는 방법을 제공
- 비동기식 함수로 정의하여 구현함
request = prepare_the_request();
// furesponse를 받는 함수를 정의하여 response가 왔을 때 실행할 수 있도록 구현함
send_request_asynchronously(request, function(response){
display(response);
});
커링(Curry)
- 커링이란 인수를 두 개 이상 받는 함수를 분해하여 인수가 하나인 함수의 중첩 함수로 변환하는 작업을 말함
- 장점: 부분 적용한 함수를 쉽게 만들어낼 수 있음
var pow = function(exponent){
return function(base){
return Math.pow(base, exponent);
};
};
pow -> Math.pow를 커링한 것임
Math.pow(base, exponent) = pow(exponent)(base)
var square = pow(2);
var sqrt = pow(.5) ;
var cubicroot = pow(1/3);
고차 함수와 커링 함수를 조합
var sum = function(a,b){return a+b; };
var a = [1,2,3,4];
var abs_a = pow(.5)(a.map(pow(2)).reduce(sum));
'코딩 이것저것' 카테고리의 다른 글
[코딩] 모던 자바스크립트 입문: 8.11. ECMAScript6 추가된 기능 (0) | 2020.05.12 |
---|---|
[코딩]자바스크립트 핵심 가이드(3) (0) | 2020.05.05 |
[코딩] 자바스크립트 핵심 가이드(2) (0) | 2020.05.05 |
[코딩] 자바스크립트 핵심가이드(1) (0) | 2020.05.02 |
댓글