this 키워드

- 메서드가 자신이 속한 객체의 프로퍼티를 참조하려면 먼저 자신이 속한 객체를 가리키는 식별자를 참조해야 함.
- 생성자 함수 내부에서는 프로퍼티 또는 메서드를 추가하기 위해 자신이 생성할 인스턴스를 참조해야 함.

 

this (자기 참조 변수)
- 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 특수한 식별자가 필요했다.

- 자바나 c++ 같은 클래스 기반 언어 : this는 언제나 클래스가 생성하는 인스턴스를 가리킴.

- 자바스크립트 : this는 함수가 호출되는 방식에 따라 this에 바인딩될 값이 결정됨.

   - 전역에서 this는              전역 객체 window를 가리킴

   - 일반 함수 내부에서는      전역 객체 window를 가리킴  (strict mode가 적용되면 undefined가 바인딩 됨.)

   - 메서드 내부에서는          메서드를 호출할 객체를 가리킴

   - 생성자 함수 내부에서는  생성자 함수가 생성할 인스턴스를 가리킴

 

함수 호출 방식과 this 바인딩

- 동일한 함수도 다양한 방식으로 호출할 수 있음

 

const foo = function() {
	console.dir(this);
};

//1. 일반 함수 호출
foo(); //window

//2. 메서드 호출
const obj = {foo};
obj.foo(); //obj

//3. 생성자 함수 호출
new foo(); // foo{}

//4. Function.prototype.apply/call/bind 메서드에 의한 간접 호출
foo.call(bar);
foo.apply(bar);
foo.bind(bar)();

1.  일반 함수 호출

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

 

var value = 1;

const obj = {
	value: 100,
    foo() {
    	console.log("foo's this: ", this);  {value:100, foo:f}
        
        //콜백 함수 내부의 this에는 전역 객체가 바인딩됨.
        setTimeout(function () {
        	console.log("callback's this :: ", this); //window
            console.log("callback's this.value :: ", this.value); //1
        }, 100);
    }
};

obj.foo();

 

- 메서드 내부의 중첩 함수나 콜백 함수의 this 바인딩을 메서드의 this 바인딩과 일치시키기 위한 방법

   ->1)  Function.prototype.apply, call, bind 메서드 활용

   ->2) 화살표 함수 활용

 

var value = 1;

const obj = {
	value: 100,
    foo() {
    
    	//bind 함수
    	console.log("foo's this: ", this);  {value:100, foo:f}
        setTimeout(function () {
           console.log(this.value); //100
        }.bind(this), 100);
        
        //화살표 함수 내부의 this는 상위 스코프의 this를 가리킴
        setTimeout(() => console.log(this.value), 100);
    }
};

obj.foo();

 

2. apply, call, bind 메서드에 의한 간접 호출

- apply, call의 대표적인 용도 : arguments 객체와 같은 유사 배열 객체에 배열 메서드를 사용하는 경우

   - arguments는 배열이 아니기 때문에 Array.prototype.slice와 같은 배열의 메서드를 사용하지 못하나 apply 나 call 메서드로 가능

function convertArgsToArray() {
	console.log(arguments);
    
    //arguments 객체를 배열로 변환
    const arr = Array.prototype.slice.call(arguments);
    console.log(arr);
    
    return arr;
}

convertArgsToArray(1, 2, 3); // [1,2,3]

 

- bind 메서드는 apply와 bind와 달리 함수를 호출하지 않고,

첫 번째 인수로 전달한 값으로 this 바인딩이 교체된 함수를 새롭게 생성해 반환

 -> 메서드의 this와 메서드 내부의 중첩 함수 또는 콜백 함수의 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)()); // { a:1 }

+ Recent posts