함수

2014. 10. 27. 11:42 나홀로스터디/JS 완벽가이드


8장 함수

이 포스팅은 "자바스크립트 완벽 가이드(인사이트, 송인철,이동기,이유원,황인석 옮김)"에서 발췌 요약한 것입니다.
 
8.1 함수 정의와 호출
8.2 함수 전달인자
8.3 데이터로서의 함수
8.4 메서드로서의 함수
8.5 생성자 함수
8.6 함수 프로퍼티와 메서드
8.7 유용한 함수들
8.8 함수 유효 범위와 클로저
8.9 function() 생성자



함수란 한 번 정의되면 임의 횟수에 거쳐 호출되거나 실행될 수 있는 자바 스크립트 코드 블록으로 매개변수(parameter) 혹은 전달인자(arguments)라 불리는 지역 변수를 가질수 있는데 이 변수의 값은 함수가 호출되는 시점에 주어진다. 객체상에서 호출되는 함수는 메서드라 칭하며 이때 객체는 함수의 암묵적 전달인자로 전달된다.

 

8.1 함수 정의와 호출
가장 일반적인 방법은 function문을 사용하는 것인데 이 문법은 function 키워드로 시작하며 다음과 같은 항목들이 따라온다

함수의 이름
괄호() 안에 0개 혹은 임의 개수의 매개변수 이름을 쉼표로 분리한 목록
중괄호 {} 안에 함수의 몸체를 구성하는 자바스크립트 문장들


만약 함수에 return 문이 없으면 단순히 함수 몸체를 이루는 문장들을 하나씩 실행한 뒤에 undefined 값을 호출자에게로 반환한다.
함수를 호출할 때에는 이름 뒤에 괄호() 연산자가 따라오고 이 괄호 안에는 선택적으로 전달인자 값(또는 표현식)을 쉼표로 분리하여 연결한 목록이 위치한다.
만약 함수가 기대하는 개수보다 많은 수의 전달인자를 전달하면 추가분의 전달인자들을 무시하고 만약 기대하는 개수보다 적은 수의 전달인자를 전달하면 빠뜨린 매개변수에는 undefined 값이 할당된다.


8.1.1 중첩된 함수
자바스크립트에서 함수는 다른 함수 안에 중첩되어 정의될 수 있는데 중첩된 함수는 그 함수가 중첩되어 위치하는 함수의 최상위 레벨에서만 정의될 수 있다.


8.1.2 함수 리터럴
함수 리터럴은 이름 없는 함수를 정의하는데 사용되는 표현식으로 자바스크립트 문장이 아니라 표현식으로 사용된다.

function f(x){ returnn x*x;}   // function문
var f = function(x){ return x*x }   // 함수 리터럴 

한번만 사용되고 버려지기 때문에 일회용 함수를 정의하는데 적합하고 리터럴 표현식에 의해 기술된 함수는 변수에 저장될 수 있고 다른 함수에 전달인자로 전달될 수 있고 곧바로 호출될 수도 있다.


8.1.3 함수 이름 붙이기
함수 이름은 일반적으로 동사 혹은 동사로 시작하는 구절로 관습적으로 소문자로 시작하고 내부적으로만 사용하거나 숨겨진 함수로 사용하려면 밑줄 문자로 시작한다.

 


8.2 함수 전달인자


8.2.1 생략 가능한 전달인자
생략 가능한 전달인자를 사용하여 함수를 작성할 때는 생략 가능한 것들을 함수 전달인자 목록의 끝에 위치하게 하여 호출할 때에 임의로 생략할 수 있게 하는 것이 중요하다


8.2.2 가변 길이 전달인자 목록: 전달인자 객체
함수 몸체에서 식별자 arguments는 특별한 의미를 지니는데  arguments는 Arguments 객체를 참조하는 특별한 프로퍼티다. 이 객체는 배열과 유사한 객체로서 함수에 전달된 전달인자의 값을 전달인자 이름이 아니라 숫자를 사용해 접근하기 위한 방법을 제공한다. 전달인자가 없는 객체는 arguments[1] 로 접근할수 있다.

Arguments객체는 숫자 인덱스가 붙은 배열 원소들과 length 프로퍼티를 정의한다.
만약 함수에 이름붙은 전달인자가 있으면 Arguments 객체의 배열 원소는 함수 전달인자를 담은 지역 변수의 별칭이 된다.


8.2.2.1 callee 프로퍼티
 Arguments 객체는 배열 원소뿐만 아니라 현재 실행되고 있는 자기 자신을 재귀적으로 호출할수 있는 callee 프로퍼티를 추가로 정의한다.


 8.2.3 객체 프로퍼티를 전달인자로 사용하기
 전달인자를 순서에 관계없이 이름의 쌍으로 전달해 주는 방식의 함수 호출을 구현하려면 우선 하나의 객체를 전달인자로 받는 함수를 정의하고 함수의 사용자로 하여금 함수에서 필요로 하는 이름과 값의 쌍들을 객체 리터럴로 정의하여 전달하게 하면 된다.


 8.2.4 전달인자 데이터 타입
 자바스크립트에서는 필요에 따라 자유롭게 데이터 타입을 변환하기 때문에 만약 문자열 전달인자를 기대하는 함수를 작성하고 이 함수를 다른 데이터 타입의 값과 함께 호출하면 함수가 그 값을 문자열로 쓰려는 시점에 문자열로의 변환 작업이 수행된다.

 

 

 8.3 데이터로서의 함수
자바스크립트에서 함수는 변수에 할당되거나 객체 프로퍼티와 배열 원소들에 저장될 수 있고 함수의 전달인자 등으로도 사용될 수 있다.

 

8.4 메서드로서의 함수
메서드는 객체 프로퍼티에 저장되어 객체를 통해 호출할 수 있는 자바스크립트 함수에 지나지 않는다. 메서드의 몸체 안에는 this 라는 키워드 값이 있다.
만약 함수를 메서드로서가 아니라 함수로 호출했다면 this 키워드는 전역객체를 가리킨다.

 


8.5 생성자 함수
생성자 함수는 객체의 프로퍼티들을 초기화하려는 함수로 new 연산자와 함께 사용될 의도로 저장된다.

 

8.6 함수 프로퍼티와 메서드
함수에 대해 typeof 연산자를 사용하면 "function" 문자열을 반환한다. 그러나 실제로 함수는 특수화된 종류의 자바스크립트 객체다.


8.6.1 length 프로퍼티
함수의 몸체 안 arguments 배열의 length 프로퍼티는 함수가 건네받은 전달인자의 개수를 명시한다. Function 객체의 length 프로퍼티는 함수에 선언된 매개변수가 정확히 몇개인지 명시한다.
arguments.length 와는 달리 length 프로퍼티는 함수 몸체의 안과 밖에서 모두 사용할 수 있다.


8.6.2 prototype 프로퍼티
prototype 객체는 함수가 new 연산자를 통해 생성자로 사용될 때 새 객체를 정의하는 과정에서 중요한 역할을 수행한다.


8.6.3 나만의 함수 프로퍼티 정의하기
존재가 유지되는 변수를 사용해야 할 경우 정보를 Function 객체의 프로퍼티에 저장하는것이 더 좋다.


8.6.4 apply() 와 call() 메서드
모든 함수에 대하여 call()과 applay() 메서드를 정의할수 있는데 이 메서드를 사용하면 함수가 마치 다른 어떤 객체의 메서드인 것처럼 호출할 수 있다. call()과 apply() 메서드의 첫 번재 전달인자는 함수가 소속되어 호출될 객체를 지정하며 이 전달인자는 함수 몸체 안에서 this 키워드 값이된다.
apply() 메서드는 call() 메서드와 유사하지만 함수로 건네줄 전달인자들을 배열로 지정한다는 점이 다르다.

 


8.7 유용한 함수들



8.8 함수 유효 범위와 클로저
자바스크립트 함수의 몸체는 전역 유효 범위와는 다른 지역 유효 범위 상에서 실행된다.


8.8.1 어휘적 유효 범위
함수가 정의될 때는 현재의 유효 범위 체인이 저장되며 이 것은 함수의 내부 상태 중 일부가 된다. 중첩된 함수를 정의하면 유효 범위는 함수를 포함하며 이는 중첩된 함수가 그 함수를 포함하는 함수의 모든 전달인자와 지역 변수들에 접근할 수 있음을 의미한다.


8.8.2 호출 객체
자바스크립트 인터프리터가 함수를 호출할 때엔 먼저 유효 범위를 함수가 정의될 당시의 효력을 지니는 유효 범위 체인으로 설정하고 새로운 객체를 생성하여 유효 범위 체인의 맨 앞에 추가한다. 이 호출 객체는 함수의 Arguments 객체를 가리키는 arguments 프로퍼티로 초기화 된다.


8.8.3 네임스페이스로서의 호출 객체
코드의 충돌을 해결하기 위한 해답은 코드를 함수 안에 넣고 함수를 호출하는 것이다. 이 경우 변수들은 함수의 호출 객체 안에 정의된다.

function init(){
  // 코드를 여기에 넣는다. } init();

이 코드는 함수를 가리키는 단 한 개의 프로퍼티 init을 전역 네임스페이스에 추가하는데 만약 단 한 개의 프로퍼티를 추가하는 것도 많다고 생각되면 익명 함수를 정의하고 호출하는 단일 표현식을 사용할 수 있다.

(function(){   // 코드를 여기에 넣는다 })();  // 함수 리터럴을 종결하고 호출한다.


8.8.4 클로저로서의 중첩된 함수
자바스크립트가 중첩된 함수를 허용한다는 사실, 함수를 데이터로 사용할 수 있다는 사실, 어휘적 유효 범위를 사용한다는 사실은 함께 상호작용하여 매우 강력한 결과를 낸다.
자바스크립트에서 함수는 다른 모든 값과 마찬가지로 데이터다. 따라서 함수는 다른 함수에 의해 반환될 수 있고 객체에 프로퍼티로 할당될 수 잇으며 또한 배열 등에 저장될 수도 있다.

자바스크립트 함수는 실행될 코드와 이 함수가 실행될 유효 범위의 조합이다. 이러한 코드와 유효 범위의 조합은 클로저로 알려져 있고 모든 자바스크립트 함수는 클로저다.


8.8.4.1 클로저 예
클로저를 사용하면 사라지지 않는 값을 저장하기 위한 용도로 사용할수 있고 private 속성을 지니는 변수를 생성할 수 있다.
가장 자연스러운 클로저 사용 예는 스티브옌의 중단점 기능구현으로 클로저를 사용하여 함수 안의 현재 유효 범위(지역 변수들과 함수의 전달인자들을 포함하는)를 포착하고 이를 전역 함수인 eval()과 함께 사용함으로써 포착한 유효 범위 안의 값을 조사할수 있게 한다. eval()은 자바스크립트 코드를 담은 문자열을 평가하고 그 값을 반환한다.
inspect()함수는 사용자에게 텍스트를 출력하고 또 사용자에게 문자열을 입력받기 위해서 .Window.prompt() 메서드를 사용한다.


8.8.4.2 클로저와 인터넷 익스플로러의 메모리 누수 현상
IE 웹 브라우저가 사용하는 가비지 컬렉션 기법은 ActiveX 객체와 클라이언트 측 DOM 엘리먼트에 대해 취약하다.
참조의 수가 0이 되는 순간 객체를 메모리상에서 제거하는 방식을 사용하는데 이 방식은 순환 형태의 참조가 존재할 경우 실패한다.

 

 

8.9 function() 생성자
함수는 일반적으로 함수 정의 문장이나 함수 리터럴 표현식의 function 키워드를 사용하여 정의된다. 또한 Function() 생성자를 사용해서도 정의될 수 있다.

var f = new Function("x", "y", "return x*y;");
function f(x,y){return x*y}; 

Function() 생성자는 함수 리터럴과 마찬가지로 이름이 없는 익명 함수를 생성하는데 보통 함수 리터럴을 사용하는 것보다 난해하기 때문에 널리 쓰이지는 않는다.

Function() 생성자를 사용하면 실행시점에 자바스크립트 코드를 동적으로 생성하고 컴파일할 수 있다.
Function() 생성자는 호출될때마다 함수 몸체를 파싱하고 새로운 함수 객체를 생성한다. 반면 루프와 함수안에 함수 리터럴이나 중첩된 함수는 그것이 나타날 때마다 매번 다시 컴파일되지 않는다.
Function() 생성자의 가장 중요한 점은 생성된 함수가 어휘적 유효 범위를 사용하지 않는다는 것이다.


 

'나홀로스터디 > JS 완벽가이드' 카테고리의 다른 글

문서 스크립팅  (0) 2014.11.26
웹 브라우저와 자바스크립트  (0) 2014.11.18
객체와 배열  (0) 2014.10.20
문장  (0) 2014.10.16
표현식과 연산자  (0) 2014.10.13
Copyright © HuckleberryM All Rights Reserved | JB All In One Designed by CMSFactory.NET