I. 들어가며 :
java의 함수와 다른 JavaScript 특유의 함수관련 개념 및 용어정리 위한 것이다.
I. 함수표현식
1. 익명함수
함수는 일급객체여서 일반변수처럼 변수명을 할당 할 수있다.
이 경우 함수가 복사된것이 아니라 함수의 참조값을 변수에 대입하게 되는 것이다.
결국 함수 호출은 변수명으로 해야한다.
var foo = function(a,b){ };
var bar = foo;
참고로 함수명과 변수를 가진 익명함수는 유사한것으로 볼수있다
결국 함수명으로 호출한다는 것은 변수명으로 호출한 것처럼 볼 수있기 때문이다.
II. 함수 호이스팅
변수 호이스팅은 변수를 선언 후 대입하기 이전에 변수출력을 하면 undefined 가 나온다
이유는 DIA 단계에서 A이전 이기 때문이다. (변수 호이스팅은 3단계가 분리되어서 나타난다)
'함수선언문'으로 정의된 함수의 경우 호이스팅은 DIA가 한번에 이루어진다. 따라서 함수선언위치와 상관없이 어디에서나 호출이 가능하다.
'함수표현식'의 경우에는 typeError가 발생한다. 왜냐하면 함수호이스팅이 아니라 변수호이스팅이 발생하기 때문이다.
(한편 함수표현식의 이점은 클로져로 사용하거나, 콜백으로 사용이 가능하다)
III. 일급객체
일반객체와의 차이는 함수는 호출할 수있다는 점
일반변수와 같이 이용이 가능한 객체를 의미한다.
IV. 함수객체의 프로퍼티
1. 들어가며
함수도 객체이다. 그렇기 때문에 프로퍼티를 가질수있다.
2. __proto__ 접근자 프로퍼티
객체에는 내부 슬롯으로 [[prototype]]가 있다. 이는 함수간 공유프로퍼티(객체간 상속)를 나타낸다.
[[prototype]] 에 직접 접근할수없기 때문에 __proto__라는 접근자 프로퍼티로 접근을 한다.
여기서 __proto__ 는 객체가 직접소유한것이 아니라 [모든객체들의 프로토타입 프로퍼티(object.prototype)]이다. 결국 모든객체는 상속으로 사용이 가능하다.
3. prototype 프로퍼티
일반 객체와 달리 함수객체만이 소유하는 것이다.
함수가 객체를 생성하는 생성자 함수로 사용 될때이다.
즉 생성자 함수가 생성한 인스턴스의 프로토타입객체이다.
V. 함수의 다양한 형태
다음 내부함수와 콜백함수의 경우 JS에서만 볼 수있는 형태이다. 주의를 가지고 보아야한다
특히 흥미로운 것은 내부함수와 콜백함수는 this의 대상이 바뀐다
왜냐하면 this는 함수가 호출될 때 어떤 객체에 바인딩되느냐인데,
이들에 의한 this는 의도치 않게 다른 객체에 바인딩된다.
즉 두함수 다 주로 전역객체(window)에 쉽게 바인딩될 수있다.
1. 내부함수
함수 내부에 정의된 함수를 의미한다.
내부 함수는 외부함수의 변수를 이용할수있다. 그러나 외부함수는 내부함수의 변수에 접근할 수 없다.
또한 내부함수는 부모함수보다 보다 외부에서 접근할수 없다.
2. 콜백함수
콜백함수란 함수를 명시적 호출하는 것이 아니라, 특정한 이벤트(사건)이 발생했을 때 호출하는 함수를 의미한다.
대표적인 예시로 이벤트리스너, 타임아웃함수가 있다.
즉 특정함수의 매개변수로 들어가고, 특정시점에 그 콜백 함수가 호출되는 것이다.
<예 1>
button.addEventListener('click', function() {
console.log('button clicked!');
});
예컨데 addEventListener의 매개변수로 함수가 있다.(이 경우 콜백큐에 들어가서 호출을 기다리고있음) 이 함수는 명시적으로 호출하는것이 아니라, click라는 특정시점에 호출된다.
<예2>
setTimeout(function () {
console.log('1초 후 출력된다.');
}, 1000);
이것도 마찬가지이다. setTimeout()함수의 매개변수로 받은 함수는 곧바로 호출되는 것이 아니라,(이 경우 콜백큐에 들어가서 호출을 기다리고있음) 1000(1초)가 지난 특정시점에 호출된다
VI. this를 중심으로
1. 함수 호출
2. 메소드 호출
var obj1 = {
name: 'Lee',
sayName: function() {
console.log(this.name);
}
}
var obj2 = {
name: 'Kim'
}
obj2.sayName = obj1.sayName;
obj1.sayName();
obj2.sayName();
this에 대해서 논의 하기 이전에 하나 깨달은 것이 있다.
비록 obj1에 프로퍼티로 sayName이라는 메소드를 정의했지만, 이것은 obj1 객체안에 직접 공간이 할당 혹은 대입 된것이 아니라, 일반적인 경우와 마찬가지로 단순히 메소드의 참조값을 저장할 뿐이다.
그렇게 때문에 obj2에 다른 객체(obj1)의 메소드를 대입해도 이것은 결국 메소드의 참조값이 대입되는것이기 때문에 obj2 객체는 불편해 할필요없다
즉 어차피 obj1도 자기안에 프로퍼티로 선언했더라도, 빌려쓰는 것에 불과하기 때문이다.
1. 보충
2. 회고
JS만의 특이한 함수의 개념을 정리해서 속이 시원하다
특히나 this에서 나를 괴롭히는 내부함수나 콜백함수에대해서도 그 개념을 이번에 어느정도 잡을수 있어서 속이 시원하다.
'배움 __IL > addtionalFrontEnd' 카테고리의 다른 글
TIL : 웹퍼블리싱 HTML 5회 (10,11) (0) | 2023.01.30 |
---|---|
비동기적프로그래밍 정리해보기 (0) | 2023.01.19 |
TIL : 웹퍼블리싱 HTML 4회 (8,9) (0) | 2023.01.07 |
TIL : 웹퍼블리싱 HTML 3회 (6,7) (0) | 2023.01.06 |
TIL : DOM 2회 (0) | 2023.01.05 |