위대한 쇼맨 this is me 노래 아시나요? 한 번 듣고 가시죠
3주차 자스핑에서는 먼저 this를 알아보겠습니당.
this 키워드
📌 객체는 프로퍼티(상태) + 메서드(동작)를 하나의 논리적인 단위로 묶은 복합적인 자료구조
- 메서드(동작)는 자신이 속한 객체의 프로퍼티(상태)를 참조하고 변경할 수 있어야 한다.
- 이때 메서드가 자신이 속한 객체의 프로퍼티를 참조하려면 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야 한다.
◽ 객체 리터럴 방식으로 생성한 객체의 경우
해당 방식은 메서드 내부에서 메서드 자신이 속한 객체를 가리키는 식별자를 재귀적으로 참조할 수 있다.
const study = {
name: javacript; // 프로퍼티 : 객체 고유의 상태 데이터
getName(){
// 이 메서드가 자신이 속한 객체의 프로퍼티나 다른 에서드를 참조하려면
// 지신이 속한 객체인 study을 참조할 수 있어야 한다.
return study.name;
}
}
- 참조 표현식이 평가되는 시점은 getName 메서드가 호출되어 함수 몸체가 실행되는 시점이다
- 객체 리터럴은 study 변수에 할당되기 직전에 평가된다. 따라서 getName 메서드가 호출되는 시점에는 이미 객체 리터럴의 평가가 완료되어 객체가 생성되었고 study 식별자에 생성된 객체가 할당된 이후다. 따라서 메서드 내부에서 study을 참조할 수 있다.
⇒ 자기 자신이 속한 객체를 재귀적으로 참조하는 방식은 바람직하지 않다.
◽ 생성자 함수로 인스턴스를 생성하는 경우
생성자 함수 내부에서는 프로퍼티나 메서드를 추가하기 위해 자신이 생성할 인스턴스를 참조할 수 있어야 한다.
생성자 함수에 의한 객체 생성 방식 :
- 생성자 함수를 정의
- new 연산자와 함께 생성자 함수를 호출
⇒ 즉, 생성자 함수로 인스턴스를 생성하려면 먼저 생성자 함수가 존재해야 한다.
- 생성자 함수를 정의하는 시점에는 아직 인스턴스를 생성하기 이전이므로 생성자 함수가 생성할 인스턴스를 가리키는 식별자를 알 수 없다. 따라서 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 특수한 식별자가 필요하다.
⇒ this 라는 특수한 식별자 제공
📌 this : 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수이다.
- this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
- 함수를 호출하면 arguments객체와 this가 암묵적으로 함수 내부에 전달된다.
- this도 arguments객체 처럼 지역변수로 사용 가능하다.
- this 바인딩(가리키는 값)은 함수 호출 방식에 의해 동적으로 결정된다.
📌 this 바인딩 : this가 가리킬 객체를 바인딩 하는 것.
- 바인딩 : 식별자와 값을 연결하는 과정
자바나 c++의 this는 언제나 클래스가 생성하는 인스턴스를 가리킨다. 하지만 자바스크립트의 this는 함수가 호출되는 방식에 따라 this에 바인딩이 동적으로 결정된다.
함수 호출 방식과 this 바인딩
this 바인딩은 함수가 어떻게 호출되었는지에 따라 동적으로 결정된다.
렉시컬 스코프와 this 바인딩 : 함수의 상위 스코프를 결정하는 방식인 렉시컬 스코프는 함수 정의가 평가되어 함수 객체가 생성되는 시점에 상위 스코프를 결정한다. 하지만 this 바인딩은 함수 호출 시점에 결정된다.
🔹 일반 함수 호출(중첩 함수, 콜백 함수 포함) : 전역 객체(global object)가 바인딩
- this는 객체의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수이므로 객체를 생성하지 않는 일반 함수에서는 this는 의미 없다. 따라서 strict mode에서 일반 함수의 this는 undefined → 사용할 일이 없기 때문
- 콜백 함수가 일반 함수로 호출된다면 콜백 함수 내부의 this에도 전역 객체가 바인딩 된다. 어떠한 함수라도 일반 함수로 호출되면 this에 전역 객체가 바인딩 된다.
// setTImeout 안에도 전역 객체가 this에 바인딩 되어 value가 100이 아닌 1이 나온다.
var value = 1;
const obj = {
value: 100,
foo() {
console.log("foo'5 this: ", this); // {valueγ 1", foo: f}
//콜백 함수의 내부의 this에는 전역 객체가 바인딩된다.
setTImeout(functlon(){
console.log("callback'sthis2",this);//window
console.log("caUback,sthis.value:'',this.value); // 1
},100);
};
obj.foo();
메서드 내부의 중첩 함수나 콜백함수의 this 바인딩을 메서드의 this 바인딩과 일치시키기 위한 방법
- that
- bind
- 화살표 함수 - 화살표 함수의 this는 선언 시점에 정적으로 결정된다! 그리고 화살표 함수가 정의된 상위 스코프의 this를 가진다. 화살표 함수는 자신만의 this를 가지지 않고 함수가 작성된 외부 스코프의 this를 상속 받는다. 그래서 생성자로 사용하지 못한다.
🔹 메서드 호출 : 메서드를 호출한 객체가 바인딩
- 메서드 내부의 this는 메서드를 소유한 객체가 아닌 메서드를 호출한 객체가 바인딩된다.
const 자스핑 = {
name: 김고은
getName(){
return this.name;
}
}
console.log(person.getName());
- getName 메서드는 person 객체의 메서드로 정의되어있다.
- 메서드는 프로퍼티에 바인딩된 함수이다.
- getName 프로퍼티가 가리키는 함수 객체는 는 person객체에 포함된 것이 아니라 독립적으로 존재하는 별도의 객체이다.
⇒ getName 프로퍼티가 함수 객체를 가리키고 있을 뿐이다.
- 따라서 getName 메서드(getName 프로퍼티가 가리키는 함수 객체)는 다른 객체의 메서드가 될 수도, 일반 변수에 할당하여 일반 함수로 호출될 수도 있다.
🔹 생성자 함수 호출 : 생성자 함수가 (미래에) 생성할 인스턴스가 바인딩
- 생성자 함수 : 객체(인스턴스)를 생성하는 함수
+ 더하여
apply. call, bind 메서드는 Function.prototype의 메서드이다 → 즉 이들 메서드는 모든 함수가 상속받아 사용 할 수 있다.
apply, call, bind가 함수의 호출/생성에 사용되는 경우 함수 내의 this는 인수로 전달된 객체이다.
자세한 건 나중에 알아보자 ,,,
마치며 ...
'메서드는 프로퍼티에 바인딩된 함수이다' 라는 것을 처음 알게 되었습니다. 객체의 메서드는 객체에 포함된 것이 아니라 독립적으로 존재하는 별도의 객체라는 점을 배워갈 수 있었습니다. 당연히 객체에 포함되는 거 인줄 알았는데 ..! 그래서 한 객체의 메서드를 다른 객체의 메서드로 만들거나 변수에 할당하여 일반 함수처럼 호출할 수 있다는 것도 너무너무 신기하네용 더 열심히 공부해야겠다.
'자스핑' 카테고리의 다른 글
[week 04] 비동기 처리 (Event Loop, Promise, Callback, Async/Await) (0) | 2024.11.21 |
---|---|
[week 04] 비동기 처리 (Event Loop, Promise, Callback, Async/Await) (6) | 2024.11.20 |
[week3] this is .. (0) | 2024.11.13 |
[week 3] 콜백함수 , this , 클로저 (0) | 2024.11.13 |
[week 02] 실행 컨텍스트와 스코프, 호이스팅 (1) | 2024.11.07 |