Skip to content

Commit b6d2d47

Browse files
committed
JS - function 정리
1 parent 7b96152 commit b6d2d47

4 files changed

Lines changed: 196 additions & 0 deletions

File tree

Modern JS/JS_Function.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# JS Function
2+
3+
- [JS Function](#js-function)
4+
- [함수의 정의](#%ed%95%a8%ec%88%98%ec%9d%98-%ec%a0%95%ec%9d%98)
5+
- [함수 선언 vs 함수 표현식](#%ed%95%a8%ec%88%98-%ec%84%a0%ec%96%b8-vs-%ed%95%a8%ec%88%98-%ed%91%9c%ed%98%84%ec%8b%9d)
6+
- [호이스팅](#%ed%98%b8%ec%9d%b4%ec%8a%a4%ed%8c%85)
7+
- [Function 인자 가변 길이 인수(Arguments 객체)](#function-%ec%9d%b8%ec%9e%90-%ea%b0%80%eb%b3%80-%ea%b8%b8%ec%9d%b4-%ec%9d%b8%ec%88%98arguments-%ea%b0%9d%ec%b2%b4)
8+
- [[ [Prototype] ] 접근자 __ proto __ 프로퍼티](#prototype--%ec%a0%91%ea%b7%bc%ec%9e%90--proto--%ed%94%84%eb%a1%9c%ed%8d%bc%ed%8b%b0)
9+
- [prototype 객체 변경](#prototype-%ea%b0%9d%ec%b2%b4-%eb%b3%80%ea%b2%bd)
10+
- [실행 컨텍스트(Excution Context)](#%ec%8b%a4%ed%96%89-%ec%bb%a8%ed%85%8d%ec%8a%a4%ed%8a%b8excution-context)
11+
12+
13+
## 함수의 정의
14+
15+
```js
16+
function hello(x,y){return x * y;} // 함수의 정의(함수 선언)
17+
18+
var hello = function(x,y){return x * y}; // 리터럴(anonymous function) (함수 표현식)
19+
20+
var hello = new Function("x,y","return x*y"); // Function 생성자(new 연산자)
21+
22+
var hello = (x,y) => x * y; // 화살표 함수
23+
```
24+
25+
## 함수 선언 vs 함수 표현식
26+
27+
- 함수 선언도 함수의 표현식과 같은 형태로 저장하는 방식이 같다.
28+
- 함수명과 함수 참조값을 가진 변수명이 일치하므로 함수명으로 호출되는 듯 보이지만 **사실은 변수명으로 호출된 것이다.**
29+
- 결국 함수 선언도 함수 표현식과 동일하게 **함수 리터럴 방식으로 정의되는 것이다.**
30+
```js
31+
function hello(x,y){return x * y; } // 함수의 정의(함수 선언)
32+
33+
// INNER CORER
34+
var hello = function hello(x,y){return x * y; } // 함수의 정의(함수 선언)
35+
```
36+
- 함수 표현식에서 함수이름을 정할 수도 있다. 하지만, 해당 함수 이름으로 호출 할 수 없다. **단지 디버깅시 해당 함수를 쉽게 알기 위함.**
37+
```js
38+
var hello = function world(x,y) {return x * y}; // 리터럴(함수 표현식)
39+
world(2,3); // Error
40+
```
41+
42+
### 호이스팅
43+
44+
- ES6의 let, const를 포함하여 모든 선언(var, let, const, function, function*, class)을 호이스팅(Hoisting)한다.
45+
- `호이스팅이란` var 선언문이나 function 선언문 등 모든 선언문이 해당 `Scope의 선두로` 옮겨 동작하는 특성을 말한다.
46+
- 즉, 모든 선언, 할당되기 이전에 참조 가능하다.
47+
48+
- 여기서 `함수 선언으로` 작업할 경우, **함수 호이스팅이 발생된다.**
49+
- 함수 호이스팅경우 **해당 함수의 객체를 생성하여(VO)** Reference Type으로 해당 **함수 선언에 연결을 한다.**
50+
- 함수 호이스팅으로 선언 이전에 함수를 호출 할 수 있다.
51+
```js
52+
console.log(hello(2,3)); // 6
53+
function hello(x,y){
54+
return x * y;
55+
}
56+
```
57+
58+
- 함수 선언의 경우와는 달리 `함수 표현식의 경우` 함수 호이스팅이 아니라 **변수 호이스팅이 발생한다.**
59+
- 변수 호이스팅경우 선언문의 이름을 **Scope의 선두로 올리고 값을 `undefined로` 부여한다.**
60+
- 즉, 함수의 객체가 생성되지 않았기 때문에 **해당 변수를 함수로 보지않는다.**
61+
```js
62+
var hello = world(5); // Error
63+
64+
var world = function(x,y) {
65+
return x * y;
66+
}
67+
```
68+
69+
## Function 인자 가변 길이 인수(Arguments 객체)
70+
71+
- **Arguments** 객체는 프로퍼티로 `length``callee`를 갖고 있다.
72+
- 해당 **Function 객체에서는** `arguments 프로퍼티` 부여
73+
- **유사 배열 객체**
74+
- length: 인수 개수
75+
- callee: 현재 실행되고 있는 함수 참조
76+
- Argumetns 객체는 인수 목록과 연동되어 **arguments 값을 바꾸면 인수도 바뀐다.**
77+
```js
78+
(function(x,y){
79+
arguments[0] = 55;
80+
console.log(x, y); // 55, 2
81+
})(2,2);
82+
```
83+
84+
## [ [Prototype] ] 접근자 __ proto __ 프로퍼티
85+
86+
- `모든 객체는` [ [Prototype] ]이라는 내부 슬롯이 있다.
87+
- [ [Prototype] ] 내부 슬롯은 **Prototype 객체를 가리킨다.**
88+
- 프로토타입 객체란 프로토타입 기반으로 **상속을 구현하기 위해 사용된다.**
89+
- 내부 슬롯을 직접 접근을 못하므로 **`__ proto __ 접근자 프로퍼티로` 접근을 한다.**
90+
- 즉, 프로토타입 객체는 다른 객체에 공유 프로퍼티를 제공하는 객체를 말한다.
91+
- **prototype 프로퍼티는 함수 객체만이 소유하는 프로퍼티이다.** (일반 객체에는 prototype 프로퍼티가 없다.)
92+
- **해당 Object, Function은 리터럴 객체로 간주한다. (리터럴)**
93+
- 만약 new Object()로 할경우 Object는 생성자 함수로 구현되어있기 때문에 Object.__ proto __ === Fucntion.prototype 을 가리키게 된다.
94+
- {}.__ proto __ === Object.prototype
95+
- ![prototype](../image/function_object_prototype.png)
96+
97+
## prototype 객체 변경
98+
99+
- `prototype 타입도` **객체이다.**
100+
- prototype 객체는 **다른 임의의 객체로 변경할 수 있다.** (객체의 상속)
101+
- 프로토타입 객체를 변경하는 시점에 따라 생성된 인스턴스(객체)의 prototype이 가리키는 참조값이 달라진다.
102+
103+
```js
104+
function Hello(next) {
105+
this.next = next;
106+
}
107+
108+
var hi = new Hello('World');
109+
110+
// 프로토타입 객체의 변경
111+
Hello.prototype = { what: 'JavaScript' }; // Object로 생성된 객체 Reference 참조
112+
113+
var hey = new Hello('World!!!!');
114+
115+
console.log(hi.what); // undefined
116+
console.log(hey.what); // 'JavaScript'
117+
118+
console.log(hi.constructor); // Hello(next)
119+
console.log(hey.constructor); // Object()
120+
```
121+
122+
- 프로토타입 객체 변경 후, Hello() 생성자 함수의 Prototype 프로퍼티가 가리키는 프로토타입 객체를 Object 객체로 변경하면서 Hello.prototype.constructor 프로퍼티도 삭제되었다.
123+
- hey.constructor의 값은 프로토타입 체이닝에 의해 Object 생성자 함수가 된다.
124+
125+
## 실행 컨텍스트(Excution Context)
126+
127+
- 실행 가능한 코드(Executable Code)를 만나면 그 코드를 평가(Evaluation)하여 실행 문맥(EC)을 만든다.
128+
- **전역 코드**
129+
- **함수 코드**
130+
- eval 코드
131+
- eval 코드는 lexcal Environment가 아닌 동적 환경에 실행 된다.
132+
133+
- JS 엔진은 코드를 실행하기 위해 실행에 필요한 정보들을 알고 있어야 한다.
134+
- **변수** (전역변수, 지역변수, 매개변수, 객체의 프로퍼티)
135+
- **함수 선언**
136+
- **변수의 유효범위(Scope)**
137+
- **this**
138+
139+
- 실행 컨텍스트(EC) 프로퍼티
140+
- ![EC](./../image/EC.png)
141+
- Variable Object(VO)
142+
- value, parameter, arguments, 함수 선언
143+
- `실행 컨텍스트에 따라` **가리키는 객체가 달라진다.**
144+
- `Global Enviroment Context`
145+
- 전역 코드 즉, 매개변수가 없는 전역코드를 평가하는 시점에서, VO는 전역객체(Global Object /GO)를 가리킨다.
146+
- 초기 상태의 전역객체는 빌트인 객체와 BOM, DOM이 구현이되어 있다. (구현이 된 후 전역 실행 컨텍스트가 생성)
147+
- 전역 객체는 전역에 선언된 전역 변수와 전역 함수를 프로퍼티로 소유한다.
148+
149+
- `Funciton Context`
150+
- VO는 활성 객체(Activation Object /AO)를 가리키며 매개변수와 인수들의 정보를 배열의 형태로 담고 있는 객체인 arguments object가 추가 된다.
151+
- Scope
152+
- 스코프는 `식별자를 검색하는 매커니즘이다.`
153+
- [Variable Object + All parent(VO)]
154+
- 리스트 형식으로 현재 실행 컨텍스트의 활성 객체를 선두로 시작하여 상위 컨텍스트의 활성 객체를 가리키며 마지막으로 GO를 가리킨다.
155+
- 함수 프로퍼티인 `[ [Scope] ]`로 참조한다.
156+
- this
157+
- context object (함수를 실행시킨 객체, 전역 코드는 window(브라우저)로 부여한다.)
158+
159+
- 실행 컨텍스트 실행(처리) 순서
160+
1. 스코프 체인의 생성과 초기화
161+
2. Variable Instantiation(변수 객체화) 실행
162+
- Variable Instantiation은 Variable Object에 프로퍼티와 값을 추가하는 것을 의미한다.
163+
164+
- 프로퍼티 값 설정 순서
165+
1. (`Function Code인 경우)` `매개변수(parameter)가` Variable Object의 프로퍼티 `name`으로, `인수(argument)가` `value`로 설정된다.
166+
2. 대상 코드 내의 `함수 선언`(함수 표현식 제외)을 대상으로 `함수명이` Variable Object`name`으로, 생성된 `함수 객체가` `value`로 설정된다.**(함수 호이스팅)**
167+
3. 대상 코드 내의 `변수 선언을` 대상으로` 변수명이` Variable Object`name`으로, `undefined가` `value`로 설정된다.(변수 호이스팅)
168+
169+
- 변수(프로퍼티) 선언 처리
170+
1. 선언 단계(Declaration phase)
171+
- 변수 객체(Variable Object)에 변수를 등록한다. 이 변수 객체는 스코프가 참조할 수 있는 대상이 된다.
172+
2. 초기화 단계(Initialization phase)
173+
- 변수 객체(Variable Object)에 등록된 변수를 메모리에 할당한다. 이 단계에서 변수는 `undefined로` 초기화된다.
174+
3. 할당 단계(Assignment phase)
175+
- `EC가 구성된 후` 전체 코드를 순차적으로 실행될 때 시점이다.
176+
- `undefined로` 초기화된 변수에 실제값을 할당한다.
177+
3. this value 결정
178+
179+
- 실행 가능한 함수 code
180+
```js
181+
var a = 'testA';
182+
183+
function outterA() {
184+
var b = 'testB';
185+
186+
function nestedB() {
187+
var c = 'testC';
188+
console.log(a,b,c);
189+
}
190+
nestedB();
191+
}
192+
193+
outterA();
194+
```
195+
196+
- ![EC, GO, AO](./../image/EC_stack.png)

image/EC.png

5.33 KB
Loading

image/EC_stack.png

27 KB
Loading
56.4 KB
Loading

0 commit comments

Comments
 (0)