공삼
article thumbnail


이 글은 우아한Tech 영상을 참고하여 작성하였습니다.

https://www.youtube.com/watch?v=7RiMu2DQrb4 

 


this 란?

this는 현재 실행중인 함수나 메서드가 속한 객체참조하는 키워드이다. 

 

this를 사용하여 현재 실행중인 컨텍스트 내에서 사용되는 객체에 접근할 수 있다. 

  • 🙌 브라우저 --> this는 window 다. window에 탑재된 속성들이 출력되는 것을 볼 수 있다.
  • 🙌 노드 --> 모듈을 가리킨다. 콘솔로그에 노드의 this를 출력하면 텅텅 빈 객체가 출력이 된다. globalThis 를 출력하면 노드에서 사용되는 전역 객체들이 출력된다.

 

바인딩 (Binding) 이란?

먼저 자바스크립트에서 모든 함수(Function)은 this를 갖고 있다. 

 

함수가 호출될때마다 이 this가 가르키는 객체가 결정된다. 

 

이렇게 동적으로 this가 결정되는 것을 "this가 객체 (SomeObject)에 바인딩 된다." 라고 한다.

 

 

자바스크립트 엔진은 실행될때 모든 실행 가능한 코드(전역코드, 함수코드, eval코드) 를 파악하고 실행 문맥 (렉시컬 환경 컴포넌트, 디스 바인딩 컴포넌트 등등...) 을 만든다. 

 

정적바인딩

this라는 함수가 계속 동적으로 변경되기 때문에 이걸 정적으로 얼려버리는 방법이 있다.

 

화살표 함수를 사용하거나, 클로저, 기본 매개변수 값을 사용하는 것이다.

 

화살표 함수 사용

  • 이것은 렉시컬 환경에서 this를 기억한다.
this.myName = () => {
  console.log(`하이 ${this.name}`);
}

이런식으로 사용할 수 있다.

 

화살표 함수의 특징

  • 문법이 깔끔
  • 생성자 함수로 사용이 불가능하다.

 

클로저 (Closure)

 

함수 생성시 기본 매개변수 값

함수의 매개변수에 기본 값으로 'this'를 지정하여 정적 바인딩을 구현할 수 있다. 

function greet(name, title = 'Mr.') {
  console.log(`Hello, ${name}! I'm ${title}`);
}

const person = {
  title: 'Dr.'
};

greet.call(person, 'Alice'); // "Hello, Alice! I'm Dr."

 


동적바인딩

현재 this는 누구인지 모른다. 누가 호출하냐에 따라 this가 달라진다. 

 

동적바인딩의 종류에는 기본바인딩, 암시적 바인딩, 명시적 바인딩, new 바인딩 등이 있다.

 

기본 바인딩

함수를 단독실행하게 되면 this는 기본적으로 전역 객체에 바인딩 된다. 따라서 브라우저 실행환경에서는 윈도우 객체에 바

 

인딩이 되지만. use strict 를 통해 엄격모드를 사용하게 되면 undefiend가 된다. 

 

 

암시적 바인딩

점 바로 앞에 있는 객체에 바인딩 되는 것을 암시적 바인딩이라고 한다.

 

cosnt obj={
	name : "abc",
    getName(){
    return this.name;
    },
};
   
function showReturnValue(callback){
	console.log(callback());
}

showReturnValue(obj.getName); //undefined

하지만 이와 같은 함수가 있을땐 obj에 바인딩 되는 것이 아니라 undefined 되게 된다. 

 

이에 대한 자세한 설명은 위 링크 영상을 참고해서 보길 바란다. 

 

필자 제대로 이해못함... 아직

 

점 연산이나 대괄호 연산을 제외한 다른 연산들은 참조타입이 아닌 해당 프로퍼티의 값만 전달하게 된다. 

 

따라서 점연산을 통해 참조타입의 값을 알아내더라도 다른변수에 할당하는 순간 프로퍼티의 값이나 참조하고 있는 참조값만이 남게 된다. 

 

따라서 점연산으로 얻어낸 함수를 바로 호출하지 않으면 암시적 바인딩이 일어나기 힘들다.

 

 

명시적 바인딩

함수객체는 call, apply, bind 등의 메서드를 통해서 명시적으로 this를 바인딩할 수 잇는 방법을 제공한다. 

빨간색으로 처리된 부분이 this가 된다. 

 

인수를 전달하는 방식의 차이만 있을 뿐 배열이나 유사배열 형태로 가능하다. 

 

new 바인딩

new 연산자로 호출하면

  1. 새로운 객체 생성
  2. 함수코드 실행
  3. 새로 생성한 객체 반환

순으로 실행된다. 

 

이 과정에서 this는 1번 새로운 객체에 바인딩 된다. 

 

{
	obj={}		//create new object
    this = obj		//bind
    
    this.name = "abc"		//obj:{name: "abc"}
    
    return this
}

간단한 예시이다. 

 

프로퍼티가 정해진 객체를 반환하는 생성자의 역할을 수행한다. 

 

 

우선순위

 

new 바인딩   >   암시적 바인딩  >   명시적 바인딩   >   기본 바인딩

 

 


동적 바인딩을 위한 메서드 (call, apply, bind)

 

Call 메서드

'call' 메서드는 함수를 호출하면서 특정 객체를 함수의 'this' 로 지정할 수 있게 해준다. 

 

function greet(name) {
    console.log(`Hello, ${name}! I'm ${this.title}`);
}

const person = { title: 'Mr.' }; //특정 객체

greet.call(person, 'John'); // Hello, John! I'm Mr.

 

apply 메서드

'apply' 메서드는 'call'과 유사하지만, 인자를 배열로 전달한다. 주로 인자가 동적인 경우에 유용하다.

function sum(a, b) {
    console.log(a + b);
}

sum.apply(null, [5, 10]); // 15

 

bind 메서드

'bind' 메서드는 함수를 호출할 때 항상 특정 객체를 'this'로 고정시키는 역할을 한다. 

 

새로운함수를 반환하며, 원래 함수와 동일한 기능을 수행하면서도 'this' 컨텍스트가 고정된다.

 

function printName() {
    console.log(this.name);
}

const person1 = { name: 'Alice' };
const person2 = { name: 'Bob' };

const printAliceName = printName.bind(person1);
const printBobName = printName.bind(person2);

printAliceName(); // Alice
printBobName();   // Bob

 

profile

공삼

@g_three

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!