this
this란?Permalink
this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수 이다.
이 this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
this는 자바스크립트 엔진에 의해 암묵적으로 생성되고 코드 어디서든 참조할 수 있다.
자바스크립트에서 함수는
변수나 데이터에 할당할 수 있고,
다른 함수의 인수 또는 반환값으로도 사용할 수가 있다.
때문에 함수는 다양한 환경에서 호출될 수가 있다.
단독으로 호출될 수도 있고
특정 객체의 메서드로써 호출되기도하고
동일한 함수가 서로 다른 객체에 의해서 호출되기도 한다.
함수가 선언된 이후에 어떤 환경에서 어떤 객체에 의해 호출될지 예측할 수 없고
자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야하기 때문에
자바스크립트 엔진에 의해 암묵적으로 this가 생성되고 모든 함수는 this를 가지고있다.
this 바인딩Permalink
함수가 호출되면 그때마다 this가 가리키는 객체가 동적으로 결정된다.
즉, this와 this가 가리킬 객체를 바인딩하는 this 바인딩이 이루어지는데
함수가 호출되는 방식에 따라 this에 바인딩될 값이 다르다.
함수를 호출하는 방식과 바인딩되는 방식
- 일반 함수 호출 -> 기본 바인딩
- 메서드 호출 -> 암시적 바인딩
- 생성자 함수 호출 -> new 바인딩
- Function.prototype.apply/call/bind 메서드에 의한 간접 호출 -> 명시적 바인딩
💡 this 바인딩 규칙 우선순위
new 바인딩 > 명시적 바인딩 > 암시적 바인딩 > 기본 바인딩
◾ 기본 바인딩: this에 전역객체가 바인딩되는 방식으로, 브라우저에서는 window가 node에서는 global이 바인딩된다.
◾ 암시적 바인딩: 호출된 대상에 this가 바인딩되는 방식으로, 주로 호출된 객체에 this가 바인딩된다.
◾ new 바인딩: 새롭게 생성되는 대상에 this가 바인딩되는 방식으로, 주로 생성자 함수에서 새로운 객체에 this가 바인딩된다.
◾ 명시적 바인딩: 특정 대상을 직접 지정하여 this가 바인딩되는 방식이다.
일반 함수 호출Permalink
일반 함수로 호출하는 경우 함수 내부의 this에는 전역 객체가 바인딩된다.
다만 앞서 말했듯이,
this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수이므로
객체가 없는 일반 함수에서 this를 사용할 일이 없다.
참고로, strict mode가 적용된 일반 함수 내부의 this에는 undefined가 바인딩된다.
메서드 안에서의 일반 함수 호출Permalink
메서드 내에서 정의한 중첩 함수도 일반 함수로 호출되면
중첩 함수 내부의 this에는 전역 객체가 바인딩된다.
콜백함수가 일반 함수 호출Permalink
콜백 함수가 일반 함수로 호출된다면
콜백 함수 내부의 this에도 전역 객체가 바인딩된다.
메서드 호출Permalink
메서드 내부의 this는 메서드를 소유한 객체가 아닌 메서드를 호출한 객체에 바인딩된다.
생성자 함수 호출Permalink
생성자 함수 내부의 this에는 생성자 함수가 생성할 인스턴스가 바인딩된다.
암시적 바인딩의 문제점Permalink
명시적 바인딩에 대해 알아보기전에
암시적 바인딩의 문제점에 대해 알아볼 필요가 있다.
객체의 메서드는 객체 내부에 정의되더라도,
실제로는 객체에 바인딩된 것이 아니라 독립적인 함수로 존재한다.
따라서, 메서드는 다른 객체의 메서드가 될 수도 있고,
일반 변수에 할당되어 일반 함수로 호출되면 this가 원래 객체를 가리키지 않을 수도 있다.
즉, 암시적 바인딩이 항상 유지되는 것이 아니고,
한번이라도 다른 변수에 할당되거나 복제되면 this가 원래 객체가 아닌 다른 값을 가리킬 가능성이 있다.
이러한 문제를 해결하기 위해서
자바스크립트는 명시적으로 바인딩할 수 있는 방법을 제공한다.
변수를 활용한 우회 바인딩Permalink
메서드를 호출한 객체에 바인딩된 this를 변수에 따로 저장한 후,
중첩 함수 내부에서 this를 사용하는 대신, 미리 저장해둔 변수를 사용하는 방법이다.
apply call bind 메서드Permalink
apply, call, bind 메서드는 JavaScript의 내장 함수인
Function 객체의 프로토타입 객체에 정의된 메서드이다.
따라서 모든 함수 객체는 이들 메서드를 상속받아 사용할 수 있다.
apply/call/bind 메서드를 사용하여 함수를 호출할 경우,
메서드의 this와 메서드 내부의 중첩 함수 또는 콜백 함수의 this를 일치시킬 수 있다.
apply/call 메서드는 함수를 즉시 호출하는 반면,
bind 메서드는 함수를 호출하지 않고 this가 바인딩된 새로운 함수를 생성한다
call과 apply 메서드Permalink
call과 apply 메서드의 첫 번째 인자로 전달한 값으로
this 바인딩이 교체된 함수를 새롭게 생성해 반환한다.
call과 apply 메서드는 인자를 전달하는 방식말고는 동작방식이 같다.
- call 메서드에서 두번째 이후로 전달되는 인자들은 함수를 호출할때 사용할 개별적인 인자로 전달된다.
- apply 메서드에서 두번째로 전달되는 인자는 함수를 호출할때 사용할 인자들을 하나의 배열형태로 묶여서 전달된다.
bind 메서드Permalink
bind 메서드는 함수로 부터 전달 받은 this와 인자들을 바탕으로
새로운 함수를 생성하고 call과 apply와는 다르게 즉시호출하지 않는 메서드이다.
여기서 말한 새로운 함수에는 원본 함수를 참조하는 this와 인자가 들어가게 된다
그리고, 생성된 함수는 호출되기 전까지 실행되지 않고
생성된 함수를 호출하면, 미리 바인딩한 this와 인자들이 함께 적용되어 실행되게된다
화살표 함수Permalink
ES6 이후,
일반 함수 내부에서 this가 전역 객체를 가리키는 문제를 해결하고,
함수 표현식을 더 간결하게 작성하기 위해 화살표 함수가 도입되었다.
화살표 함수는 기존의 this 바인딩 과정을 생략하여, 자체적인 this를 가지지 않는 함수이다.
따라서, this를 호출하면 자신이 정의된 상위 스코프의 this를 자동으로 참조한다.
화살표 함수의 this는 상위 스코프의 this를 고정적으로 참조하므로,
call, apply, bind()를 사용해도 변경할 수 없다.
댓글남기기