Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

보근은 참고 있다

JS의 함수 본문

Language/JS

JS의 함수

보근 2021. 8. 16. 20:48

 

 

 

 

 

 

 

함수의 생성

  • 함수 선언문
  • 함수 표현식
  • Function() 생성자 함수

 

//함수 선언문
function add1(x, y) {
    return x + y;
}

//함수 표현식
var add2 = function (x, y) {
    return x + y;
};

// Function 생성자 함수
var add3 = new Function('x', 'y', 'return x + y');

console.log(add1(1, 2));	// 3
console.log(add2(1, 2));	// 3
console.log(add3(1, 2));	// 3

 

 

위의 세 가지 방법으로 생성한 함수는 모두 똑같이 동작해서 같은 결과를 보여주지만, 동작 방식의 차이가 있다. 그중 하나가 함수의 호이스팅(Function Hoisting)이다. 호이스팅이란, 코드가 실행되기 전에 메모리에 값을 저장해두는 것을 말한다.

 

add(1, 2)	// 3

function add(x, y) {
	return x + y;
}

add(2, 3)	// 5

위의 예제에서 보면, 위의 add()는 add가 함수로 정의되는 코드 전에 있지만, 실행이 잘 된다. 아래의 add() 역시 마찬가지이다. 함수 선언문으로 함수를 선언하면 이렇게 호이스팅이 일어난다.

 

add(1, 2)	// error

var add = function(x, y) {
	return x + y;
}

add(2, 3)	// 5

이 예제에서는 함수 표현식으로 함수를 선언했기 때문에 호이스팅이 일어나지 않아서 에러가 발생한다.

 

 

 

 

 

 

 

객체로써의 함수

JS에서는 함수도 객체이다. 기본 기능인 코드 실행뿐만 아니라, 프로퍼티를 가질 수 있다.

function add(x, y) {
    return x + y;
}

add.result = add(3, 2);	// result 프로퍼티 추가
add.status = "OK";		// status 프로퍼티 추가

console.dir(add6);

 

 

console.dir(add6)의 결과

 

 

 

 

JS에서 함수는 일급 객체이다. Java와 달리 함수가 인자, 배열의 요소, 리턴 값 등 함수도 일반 객체가 들어갈 수 있는 자리에는 다 들어갈 수 있다는 뜻이다. 이러한 특성으로 함수형 프로그래밍이 가능하다.

 

  • 리터럴에 의한 생성
  • 변수나 배열의 요소, 객체의 프로퍼티 등에 할당 가능
  • 함수의 인자로 전달 가능
  • 함수의 리턴 값으로 리턴 가능
  • 동적으로 프로퍼티를 생성 및 할당 가능

 

 

 

 

 

 

함수의 프로퍼티

ECMA5 명세서에는 모든 함수가 lengthprototype 프로퍼티를 가져야 한다고 기술되어 있다. 

 

  • name 프로퍼티는 함수의 이름을 나타낸다. 익명 함수는 빈 문자열이 들어간다.
  • caller 프로퍼티는 자신을 호출한 함수를 나타낸다. 여기서는 null이고, 이 프로퍼티는 deprecated.
  • arguments 프로퍼티는 함수를 호출할 때 전달된 인자 값을 나타낸다. 여기서는 호출되지 않은 상태이기 때문에 null이고, 얘도 deprecated.
  • [[Prototype]] 프로퍼티는 객체 자신의 프로토타입을 가리킨다. __prototype__을 쓰기도 하는데 그냥 같은 표현이라고 생각하면 된다.

 

모든 함수들의 프로토타입은 Function.prototype이다. 그렇다면 Function.prototype의 프로토타입은 무엇일까? Function.prototype은 함수이지만, Object.prototype을 프로토타입으로 가진다.

 

 

 

 

함수에서 length 프로퍼티는 함수의 파라미터의 개수이다.

function func0() {

}

function func1(x) {

}

function func2(x, y) {

}

function func3(x, y, z) {

}

console.log(func0.length);	// 0
console.log(func1.length);	// 1
console.log(func2.length);	// 2
console.log(func3.length);	// 3

 

 

  • 모든 객체가 가지는 프로토타입 [[Prototype]]
  • 모든 함수 객체가 가지는 prototype

위의 두 프로퍼티들은 프로토타입 객체를 가리킨다는 점에서 공통점이 있지만, 약간의 차이가 있다. [[Prototype]]은 객체 입장에서 자신의 부모 역할을 하는 프로토타입 객체를 가리키고, prototype은 이 함수가 생성자로 사용될 때 이 함수를 통해 생성된 객체의 부모 역할을 하는 프로토타입 객체를 가리킨다. 뭔 말인지 1도 모르겠다.

 

 

 

prototype 프로퍼티는 함수가 생성될 때 만들어지며, constructor 프로퍼티만을 가지는 객체를 가리킨다. constructor 프로퍼티는 다시 함수 객체를 가리킨다. 서로가 서로를 참조하는 모양이다. 

JS에서는 함수를 생성할 때, 함수 자신과 연결된 프로토타입 객체를 동시에 생성한다. 그리고 두 객체는 서로 prototype과 constructor 프로퍼티들로 서로를 참조한다.

 

 

 

 

 

여러 종류의 함수

 

콜백 함수

콜백 함수란 명시적으로 코드를 기입해 호출하는 것이 아닌, 함수를 등록해두고 어떤 이벤트가 발생하거나, 특정 시점에 도달했을 때 호출되는 함수를 말한다.

 

<script>
	window.onload = function() {
		alert('Call Back Function!!!!!!!!!!!!');
	};
</script>

 

페이지 로드 시에 콜백 함수가 호출되어 메시지가 출력된다.

 

 

 

 

 

즉시 실행 함수

함수의 정의와 동시에 바로 실행하는 함수를 즉시 실행 함수라고 한다. 익명 함수를 통해 구현하며, 최초의 한 번 호출 뒤에 재호출이 불가능하다.

 

(function (name) {
	console.log(name);
})('bogeun');

((name, age) => {
	console.log(name, age);
})('bogeun', 21);

익명 함수를 소괄호로 감싸고 뒤에 소괄호로 파라미터를 넘겨주는 모양으로 즉시 실행 함수를 작성한다. 

 

즉시 실행 함수는 jQuery같은 라이브러리를 사용할 때 많이 사용하는데, 이는 JS의 함수 유효 범위 특성 때문이다. 함수 외부에서 함수 내부의 변수들에 접근할 수 없기 때문에, 라이브러리 코드를 추가해도 변수 이름 충돌 등이 일어나지 않는다.

 

 

 

 

내부 함수

JS는 함수 코드 내부에서 또 함수를 정의할 수 있는데, 내부에 정의된 함수를 내부 함수라고 한다. 내부 함수는 클로저를 생성하거나 부모 함수 코드에서 외부에서의 접근을 막고 독립적인 헬퍼 함수를 구현하는 용도 등으로 사용된다.

 

function parent() {
	var a = 100;
	var b = 200;
    
    function child() {
    	var b = 300;
        
        console.log(a);		// 100
        console.log(b);		// 300
    }
    
    child();
}

parent();
child();		// error

 

child 함수는 parent의 변수에 접근이 가능한 것을 볼 수 있다. 이 것은 JS의 스코프 체이닝 때문에 가능하다.

그리고, parent 함수 밖에서 child 함수가 호출되지 않는 것을 알 수 있다. 내부 함수는 일반적으로 자신이 정의된 부모 함수 내부에서만 호출 가능하다.

 

하지만, 부모 함수에서 내부 함수를 외부로 리턴하면, 부모 함수 밖에서도 내부 함수를 호출하는 것이 가능하다.

 

function parent() {
	var a = 100;
    
    function child() {
        console.log(a);
    }
    
    return child;
}

var inner = parent();
inner();		// 100;

inner가 parent()를 통해 child 함수 객체를 리턴 받았다. inner를 호출하면, parent 함수 내부의 child 함수가 호출이 되고, child에는 a라는 변수가 없으니 스코프 체이닝으로 parent에서 정의된 a 변수를 출력하게 된다.

 

위와 같이 실행이 끝난 parent() 같은 부모 함수 스코프의 변수를 참조하는 inner() 같은 함수를 클로저라고 한다.

 

 

 

함수를 리턴하는 함수

JS에서 함수는 일급 객체이기 때문에, 리턴 값으로 사용할 수 있다. 이러한 특성을 통해 다양한 활용이 가능하다.

 

var self = function () {
	console.log('a');
    
	return function () {
		console.log('b');
	}
}

self = self();	// a
self();		// b

처음에 self()가 호출되었을 때는 a를 찍는 함수가 실행이 되고, 그 리턴 값으로 b를 찍는 함수를 받았기 때문에, 그 다음의 호출에는 b가 찍힌다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Language > JS' 카테고리의 다른 글

함수 호출과 this  (0) 2021.08.20
JS의 배열  (0) 2021.08.06
JS 데이터 타입과 연산자  (0) 2021.08.04
Comments