본문 바로가기
코딩 이것저것

[코딩] 자바스크립트 핵심 가이드(4)

by 글쓰는 홍차 2020. 5. 11.

이번 장은 함수에 대한 내용이다. 가장 중요하게 생각해도 되는 장이다. 함수형 자바스크립트에 대한 책도 많이 나와 있다. (추후에는 함수형 자바스크립트 입문 책도 샀으니 관련하여 정리할 예정이지만, 이 장은 자바스크립트 핵심 가이드에서 나온 내용을 주로 정리한다) 

함수는 모듈화의 근간, 코드의 재사용성, 정보의 구성 및 은닉 등에 사용, 객체의 행위를 지정하는데도 사용할 수 있음.  

함수 객체 

자바스크립트에서 함수는 객체임. 객체는 프로토타입 객체로 숨겨진 연결을 갖는 이름/값 쌍들을 집합체로 객체 중에서 객체 리터럴로 생성되는 객체는 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)); 

댓글