자바스크립트에서의 this는 어디서든 사용할 수 있으며 다른 언어와는 조금 다르게 동작합니다.

실행 컨텍스트가 생성될때 this의 바인딩이 일어나며 우선순위가있습니다.

실행 컨텍스트는 함수를 호출할때 생성되므로 또 다른 의미로는 함수를 호출할때 this가 결정된다고 할 수도 있습니다.

또한 함수의 호출마다 this가 달라질 수도 있다는 의미이기도합니다.

 

 

This

  • 전역공간에서의 this는 전역객체 (브라우저 - window, 노드 - global)를 참조

  • 메서드일 경우 호출한 객체를 this로 참조

  • 함수일 경우 this는 전역객체

  • 콜백함수는 제어권을 넘겨받은 함수가 정의한 this 참조, 정의가 없으면 전역객체

  • 생성자 함수는 생성될 인스턴스를 참조

  • call, apply, bind 같은 명시적 바인딩일 경우 인자로 전달된 객체

  • 그외 엄격모드는 undefined로 초기화 됨 (엄격, 비엄격에 차이가 있다)

 

 

전역

전역공간에서의 this는 전역객체를 가리킵니다.

전역 객체는 런타임환경에 따라 다른 이름과 정보를 가지고 있는데, 브라우저는 window, 노드환경에서는 global입니다.

console.log(this === window); // true

 

 

함수

호출한 방법에 의해 this가 결정됩니다. 

함수로서 호출하는 방법과 메서드로서 호출하는 경우에따라 this가 다른 값이 될 수 있습니다.

 

예제1)

var obj = {
	funcA : function(){
    	console.log(this);
    },
    option : {
    	funcB : function(){
    		console.log(this);
    	}
    }
};

console.log(obj.funcA()); // obj가 this임
console.log(obj.option.funcB()); // obj.option가 this임

점(.) 표기법으로 연결된 경우 마지막 점 바로 앞에 연결된 객체가 this가 됩니다.

 

 

예제2) 같은 코드라도 엄격모드와 비엄격모드에서 달라질 수 있습니다.

// 엄격모드 
function isThis(){ 
	"use strict"; 
    return this; 
};

console.log(isThis()); // undefined

// 비엄격모드 
function isThis() { 
	return this; 
};

console.log(isThis()); // Window { 0: Window, 1: ..... }

 

 

명시적방법(call, apply, bind)

상황별 this가 바인딩되는 규칙을 깨고 this에 별도의 대상을 바인딩하는 방법이 있습니다.

다만 명시적으로 별도의 this를 바인딩 할 경우 this를 예측하기 어렵다는 단점이 있습니다.

 

call

메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령입니다.

첫번째 인자로 this를 바인딩, 이후 인자들은 호출할 함수의 매개변수로 전달합니다.

var getName = function(name){
	console.log(this, name);
};

getName('hong'); // Window { ... } 'hong'

getName.call({ a : 1 }, 'hong'); // {a: 1} 'hong'

 

apply

call 메서드와 기능적으로 완전히 동일합니다.

apply 메서드는 두번째 인자를 배열로 받아서 매개변수로 지정한다는 점만 call과 다릅니다.

var getName = function(name){
	console.log(this, name);
};

getName('hong'); // Window { ... } 'hong'

getName.apply({ a : 1 }, ['hong']); // {a: 1} 'hong'

* 문자열 'hong'을 배열로 호출하지 않으면 타입에러가 발생합니다.

 

 

bind

ES5에서 추가된 기능이며 call 메서드와 비슷하지만 즉시 호출하지 않습니다.

넘겨받은 this 및 인수들을 바탕으로 새로운 함수를 반환합니다.

var getName = function(name){
	console.log(this, name);
};

getName('hong'); // Window { ... } 'hong'

var bindGetName = getName.bind({a: 1});
bindGetName('hong'); // {a: 1} 'hong'

* bind 메서드를 적용해서 새로 만든 함수는 name 프로퍼티에 동사 bind의 수동태인 bound라는 접두어가 붙으며 call과 apply보다 추적이 수월합니다.

 

 

ES6의 arrow function

함수 내부에서 this가 전역객체를 바라보는 문제를 보완하고자 this를 바인딩하지 않는 화살표 함수를 도입했습니다.

화살표 함수는 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 빠져있어 this에 접근하려고하면 스코프체인상 가장 가까운 this에 접근합니다.

즉, 상위 스코프의 this를 그대로 활용할 수 있습니다.

const car = { 
	name : avante, 
	getPrice: function() {
		return this.name;
	},
}; 

console.log(car.name()); // avante

 

 

위와같은 내용들로 인해 this가 이것이다라고 정의할 수는 없습니다.

 


 

출처

+ Recent posts