[모던딥다이브 자바스크립트] This

zzzzzang_gu·2023년 3월 24일
0

자바스크립트

목록 보기
21/23

This의 정의와 바인딩에 대하여


This??

  • This는 자바스크립트의 예약어(키워드)이다.
  • 자바스크립트의 함수는 호출될 때, 매개변수로 전달되는 인자값 이외에, arguments 객체와 This를 암묵적으로 전달 받는다.
  • This가 가르키는 값, 즉 this binding은 함수 호출 방식에 의해 동적으로 결정된다.
  • This를 통해 자신이 속한 객체 or 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
  • 화살표 함수에서의 This는 함수가 속해있는 곳의 상위 스코프의 This를 상속 받는다.
호출 방식설명
생성자 함수 this생성할 인스턴스
메서드 내부의 this메서드를 호출한 객체
전역에서의 this전역 객체 window
일반 함수 내부전역 객체 window

This 바인딩

바인딩이란 식별자와 값을 연결하는 과정을 의미한다. 변수 선언은 변수 이름(식별자)와 확보된 메모리 공간의 주소를 바인딩하는 것이다. this 바인딩은 this(키워드로 분류되지만 식별자 역할) 와 this가 가르킬 객체를 바인딩 하는것이다.


함수 호출 방식과 this 바인딩

this 바인딩은 함수 호출 방식, 즉 함수가 어떻게 호출되었는지에 따라 동적으로 결정된다.

렉시컬 스코프는 함수 정의가 평가되어 객체가 생성되는 시점에 상위 스코프를 결정한다. 하지만 this 바인딩은 함수 호출 시점에 결정된다.

주의할 점은 동일한 함수도 다양한 방식으로 후출할 수 있다.

일반 함수 호출

기본적으로 this에는 전역 객체가 바인딩된다.

var value = 1;

const obj = {
  value = 100;
  foo(){
  	console.log(this);	// {value : 100 , foo : f}
    console.log(this.value);	// 100
  }
  
  function bar(){
  	console.log(this)	//window
    console.log(this.value)	// 1
  }

  bar()
}

콜백 함수가 일반 함수로 호출된다면 콜백 함수 내부의 this에도 전역 객체가 바인딩된다.
이처럼 일반 함수로 호출된 모든 함수(중첩 함수, 콜백 함수 포함) 내부의 this에는 전역 객체가 바인딩된다.


메서드 호출

메서드 내부의 this는 메서드를 소유한 객체가 아닌 메서드를 호출한 객체에 바인딩된다.

	function Person(name){
    	this.name = name;
    }

	Person.prototype.getName = function(){
    	return this.name;
    }
	
	const me = new Person('PARK');

	//getName 메서드를 호출한 객체는 me다.
	console.log(me.getName()); // PARK
	
	Person.prototype.name = 'KIN';

	//getName 메서드를 호출한 객체는 Person.prototype 이다.
	console.log(Person.prototype.getName()); //KIM

생성자 함수 호출

생성자 함수 내부의 this에는 생성자 함수가 생성할 인스턴스가 바인딩된다.

function Circle(radius){
    this.radius = radius;
    this.get = function(){
        return 2*this.radius
    }
}

const circle1 = new Circle(5);
const circle2 = new Circle(10);

console.log(circle1.get()); //10
console.log(circle2.get());	//20

//new 연산자와 함께 호출하지 않으면 일반 함수로 동작한다.
const circle3 = Circle(15);

// 일반 함수로 호출된 circle에는 반환문이 없으므로 undefined가 반환
console.log(circle3); // undefined

//일반 함수로 호출된 circle 내부의 this는 전역 객체 window를 가리킨다.
console.log(radius); //15

Function.prototype.apply/call/bind 간접 호출

apply, call, bind 메서드는 Function.prototype의 메서드다. 즉 모든 함수가 상속받아 사용할 수 있다.

function getThisBinding(){
  	console.log(arguments);
	return this;
}
//this로 사용할 객체
const thisArg = {a : 1};

console.log(getThisBinding.apply(thisArg,[1,2,3]));
// Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
// {a : 1 }

console.log(getThisBinding.call(thisArg,1,2,3));
// Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
// {a : 1 }

apply 메서드는 호출할 함수의 인수를 배열로 묶어 전달한다. call 메서드는 호출할 함수의 인수를 쉼표로 구분한 리스트 형식으로 전달한다. 두 메서드는 인수를 전달할 방식만 다를 뿐 this로 사용할 객체를 전달하면서 함수를 호출하는 것은 동일하다.

function getThisBinding(){
	return this;
}

const thisArg = {a:1};

// bind 메서드는 첫 번째 인수로 전달한 thisArg로 this 바인딩이
//교체된 getThisBinding 함수를 새롭게 생성해 반환한다.
console.log(getThisBinding.bind(thisArg)); // getThisBinding
//bind메서드는 함수를 호출하지는 않으므로 명시적으로 호출해야 한다.
console.log(getThisBinding.bind(thisArg)());


함수 호출 방식this 바인딩
일반 함수 호출전역 객체
메서드 호출메서드를 호출한 객체
생성자 함수 호출생성자 함수가 생성할 인스턴스
apply,call,bind 메서드에 의한 간접 호출메서드에 첫번째 인수로 전달한 객체
profile
프론트엔드 개발자가 되겠습니다🔥

0개의 댓글