JS 코드의 실행
1. 어떤 코드도 없는 경우
JS 엔진은 다음 3개(실행 컨텍스트)를 초기화 한다.
실행 컨텍스트
- this : 코드가 실행되는 시점의 환경이 가리키는 객체를 의미
- 변수들 (Variable Object) : 매개변수와 인수 정보, 함수 선언(함수 표현식은 제외)을
- Scope chian : 스코프가 어떻게 연결되고 있는지를 보여줌
// 어떤 코드도 없는 경우
this : window
변수들 : {}
Scope chain : []
- JS엔진은 코드가 없어도 실행환경(실행 컨텍스트-JS를 실행했을 때의 환경) 초기화
- 스코프는 코드가 현재 실행되는 환경, 맥락(context)을 의미 -> 현재 코드에서 접근할 수 있는 변수/함수
- this 포인터/스코프에 저장된 변수들/스코프 체인 등이 환경에 포함
- this 포인터의 경우, 레퍼런스 변수로 글로벌 스코프에서는 window를 가리킴
2. JS 코드의 실행
function myFunc() {
let a = 10
let b = 20
function add(first, second) {
return first + second
}
return add(a, b)
}
myFunc(
add() : 함수 실행 컨텍스트
this : undefined
변수들 : {first:10 second:20}
Scope chain : [myFunc,global]
------------------------------------------------------------------------------------------------------------
myFunc() : 함수 실행 컨텍스트
this : undefined
변수들 : {a:10 b:20 add:function(){...} }
Scope chain : [global] // 이전의 실행 컨텍스트를 가리켜서 지금 스코프에 선언되지 않은 변수를 찾을 때
-------------------------------------------------------------------------------------------------------------
global - 전역 실행 컨텍스트
this : window
변수들 : {myFunc:function(){...}}
Scope chain : []
- 함수가 실행되면, 함수 스코프에 따라 환경이 만들어짐
- this, 함수 스코프의 변수들 , 그리고 스코프 체인이 형성
- 스코프 체인을 따라 글로벌 환경에 도달
3. JS 코드의 실행
let o = {
name: 'Jaeku',
method: function(number) {
return this.name.repeat(number)
}
}
function myFunc() {
let n = 10
return o.method(n)
}
myFunc()
o.method() : 함수 실행 컨텍스트
this : o
변수들 : {number:10}
Scope chain : [myFunc,global]
------------------------------------------------------------------------------------------------------------
myFunc() : 함수 실행 컨텍스트
this : undefined
변수들 : {n:10}
Scope chain : [global]
-------------------------------------------------------------------------------------------------------------
global : 전역 실행 컨텍스트
this : window
변수들 : {o:{...} myFunc:function(){...}}
Scope chain : []
- 객체의 메서드인 경우, 메서드의 환경의 this는 해당 객체를 가리킴
- 하지만 this가 가리키는 것은 환경에 따라 변할 수 있음
실행 컨텍스트
- 실행 컨텍스트는 JS 코드가 실행되는 환경
- 코드에서 참조하는 변수, 객체(함수 포함), this 등에 대한 레퍼런스가 있음
- 실행 컨텍스트는 전역에서 시작해, 함수가 호출될 때 스택에 쌓임
전역 실행 컨텍스트 : 자바스크립트가 실행 될 때 만들어지는 실행 컨텍스트
함수 실행 컨텍스트 : 함수가 실행될 때 만들어지는 실행 컨텍스트
참고 자료 : https://poiemaweb.com/js-execution-context
this
함수가 호출되는 상황
- 함수 호출 - 함수를 직접 호출
- 메서드 호출 - 객체의 메서드를 호출
- 생성자 호출 - 생성자 함수를 호출
- 간접 호출 - call,apply 등으로 함수를 간접 호출
- 콜백 함수 호출 - 특정 동작 이후 불려지는 함수(보통 다른 함수의 인자로 보내지는 함수)
function myFunc() {
console.log('myFunc called')
}
myFunc() // 함수를 직접 호출.
const o = {
name : 'jaeku',
printName : function() {
console.log(this.name) }
}
o.printName() // 객체의 메서드를 호출.
function Person(name) {
this.name = name
this.printName = function() {
console.log(this.name) }
}
const p = new Person('Daniel') // 생성자 호출
setTimeout(p.printName.bind(p), 1000)
// 간접 호출
- 함수는 다양한 상황(환경)에서 호출
- 함수의 호출 환경에 따라 this는 동적으로 세팅
- this가 환경에 따라 바뀌는 것을 동적 바인딩
- bind, apply, call 등으로 this가 가리키는 것을 조작 가능
let o = {
name: "jaeku",
f1: () => {
console.log("[f1] this : ", this);
},
f2: function () {
console.log("[f2] this : ", this);
} ,
};
o.f1(); // global
o.f2(); // o
setTimeout(o.f1, 10); // global
setTimeout(o.f2, 20); // global;
화살표 함수 this
- 화살표 함수 호출시 this는 함수가 생성된 환경을 가리키도록 고정 (호출된 함수를 둘러싼 실행 컨텍스트를 가리킴)
- 화살표 함수의 this는 정해지면 바꿀 수 없음
- call,bind,apply를 사용해도 바뀌지 않음
- setTimeout 등 this가 바뀌는 상황에선 유용
일반 함수 this
- 일반 함수 this는 함수를 호출된 환경을 가리키며 this는 동적으로 바뀔 수 있음 (새롭게 생성된 실행 컨텍스트를 가리킴)
- 객체의 메서드로 호출될 때 객체가 this로 할당
this 정리
우선 아래 3가지 규칙이 this와 관련한 규칙 전부입니다. 이 이외에는 없습니다.
- 객체(object)의 메소드(객체 내의 함수)가 일반 함수인 경우, this는 그 객체가 된다.
- 객체의 메소드가 화살표 함수인 경우, this는 lexical context (화살표 함수 밖 컨텍스트)이다.
- 1번도 2번도 아닌 경우의 this는 window (strict 아닐 때) 혹은 undefined(strict일 때)이다.
ES6 Rest, Spread Operator
Rest Operator
- 객체의 rest operator는 지정된 필드 외의 나머지 필드를 객체로 묶음
- 배열의 rest operator는 나머지 인자를 다시 배열로 묶음
- Rest파라미터는 항상 제일 마지막 파라미터
Spread Operator
- 묶인 배열 혹은 객체를 각각의 필드로 변환
- 객체는 또 다른 객체로의 spread를 지원
- 배열은 또 다른 배열의 인자,함수의 인자로의 spread를 지원
'Elice SW 2 > TIL' 카테고리의 다른 글
DAY 16 - TIL (0) | 2022.04.27 |
---|---|
DAY 15 - TIL (0) | 2022.04.26 |
DAY 13 - TIL (0) | 2022.04.22 |
DAY 12 - TIL (0) | 2022.04.21 |
DAY 11 - TIL (0) | 2022.04.19 |
댓글