function foo(x) {
return 0;
}
- `함수 선언문`이다. 함수를 값으로 사용한 것이 아니다.
const bar = function () { };
(function(){
})()
- `값`으로 함수를 취급한 예시이다.
function foo(x) {
x();
return function() {
};
}
const y = foo(function() {
});
- 함수를 값으로 취급할때 익명함수를 사용할 수 있다. 위에서 x와 return 값은 변수에 해당하므로, 또한 `값`에 해당하기 때문에 함수를 값으로 사용할 수 있다.
- 위와 같이 함수를 받아서 함수를 리턴하는 함수를 `일급 함수`라고 함. 리액트에서 컴포넌트를 받아서 컴포넌트를 반환하는 형식이 여기에 해당됨.
= 함수 : 코드를 묶고 있는 `값`이라 생각하자.
const foo = function foo () {
foo();
}
- 재귀 호출을 위해서는 함수의 이름을 생략하지 않는다.
- 결과가 `값`을 반환하는 경우는 "식"이다. ex) 0; 1+10; foo(); 따라서 값을 반환하는 경우 "식"에 포함 될 수 있다. 1 + 10 + foo();
- 결과가 `값`을 반환하지 않는 경우는 "문"이다. ex) 분기문(if ...), 반복문(for, while)
= 삼항연산자는 `값`을 반환하기 때문에 "식"이다.
const x = {};
x.name = 10;
- x 객체를 생성한 이후 프로퍼티를 할당할 수 있는 것을 = 동적 바인딩이라고 함.
function foo(){
this.name = 10;
}
const y = new foo();
- foo 함수의 this는 new로 생성된 객체를 가리킨다. >> 동적 바인딩
- y는 foo 함수의 인스턴트 객체를 가리킴.
console.log(y instanceof foo); // true
console.log(foo instanceof foo); // false
- instanceof 를 사용하여 누구의 인스턴트 객체인지 확인할 수 있다.
function foo(){
this.name = 10;
}
class bar {
constructor() {
this.name = 10;
}
}
- foo 를 더욱 명시적으로 다시 작성하면 아래의 bar 로 바꿀수 있다. (class 사용)
- foo 함수는 foo() or new foo() 이렇게 호출이 가능하지만 / bar 클래스는 new bar()로 만 호출이 가능하다.
= function 으로 생성자를 작성하면 두가지 방법으로 호출이 가능하기 때문에 구분이 쉽지 않다. 그러나 class로 생성자를 작성하면 더욱 명시적이게 되어서 생성자로의 호출(new)를 강제할 수 있다.
const person = {
name: `김태현`,
getName() {
return this.name;
}
}
console.log(person.getName()); // 김태현
- this가 결정되는 방식 : 호출하는 순간의 소유자와 연결이 된다. > `실행 컨텍스트`라고 함.
const person = {
name: `김태현`,
getName() {
return this.name;
}
}
console.log(person.getName()); // 김태현
const man = person.getName;
console.log(man()) // Cannot read property 'name' of undefined
- man에 getName을 할당하여 호출한 경우 소유자를 확인할 수 없다. (소유자가 벗겨진다고 표현함.) 이 경우에는 전역객체인 (노드에서는 global, 브라우저에서는 window객체)로 연결이 된다.
- 이러한 실행 컨텍스트는 button.addEventListener('click', person.getName) 와 같이 사용하는 경우 문제가 될 수 있다.
button.addEventListener('click', person.getName.bind(person));
- 이렇게 .bind(person) 이나 .call(person) 등을 사용하여 소유자가 묶인 함수를 반환할 수 있다.
const person = {
name: `김태현`,
getName: () => {
return this.name;
}
}
- 화살표 함수는 소유자가 자동으로 person에 묶여버리게 되어 실행컨텍스트는 무조건 name이 `김태현`이 되어서 문제의 소지가 없다.
function foo(x) {
return function bar() {
return x;
}
}
const f = foo(10);
console.log(f());
- function foo가 호출되면 foo의 스코프가 생긴다. foo의 스코프 안에는 현재 bar 함수가 있다. bar 함수는 스코프 체인 바깥쪽의 변수인 x 를 사용하므로, 이는 클로저 영역에 위치하게 된다. (x의 값을 캡쳐함.) = 이런 x를 클로저 라고 함.
const person = {
age: 10,
}
function makePerson() {
let age = 10;
return {
getAge() {
return age;
},
setAge(x) {
age = x > 1 && x < 130 ? x : age;
}
}
}
let p = makePerson();
console.log(p.getAge()); // 10
- 클로저를 활용하면, 위와 같은 패턴을 사용할 수 있다. person의 age는 500으로도 바꿔버릴 수 있다. 하지만클로저를 활용하면 makeperson처럼 500으로 바꿀 수 없도록 할 수있다.
'tech documents > memo' 카테고리의 다른 글
[우아한 테크러닝 3기] 클로저 (0) | 2020.09.03 |
---|---|
[우아한 테크러닝 3기] async (0) | 2020.09.03 |
[React] redux의 mapStateToProps는 언제 실행되는가? (0) | 2020.08.31 |
[Javascript] Iterator (0) | 2020.08.31 |
댓글