Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Today
Total
관리 메뉴

고리타분한 개발자

함수 (Function) - this 의 동작원리 본문

JavaScript/Garden

함수 (Function) - this 의 동작원리

sunlee334 2017. 11. 9. 00:53

다른 프로그래밍 언어에서 this가 가리키는 것과 Javascript에서 this가 가리키는 것과는 좀 다릅니다. this가 가리킬 수 있는 객체는 정확히 5종류입니다. 


// 1. Global Scope에서

// Global Scope에서도 this가 사용될 수 있고 이때에는 Global 객체를 가리킵니다.
this;

// 2. 함수를 호출할 때

// 이때에도 this는 Global 객체를 가리킵니다.
// strict 모드에서 더는 Global 객체를 가리키지 않고 대신 undefined를 가리킵니다.
monkey();

// 3. 메소드로 호출할 때

// 이 경우에는 this가 test를 가리킵니다.
test.monkey();

// 4. 생성자를 호출할 때

// new 키워드로 생성자를 실행시키는 경우에 이 생성자 안에서 this는 새로 만들어진 객체를 가리킵니다.
new monkey();

// 5. this가 가리키는 객체 정해주기.

// Function.prototype의 call이나 apply 메소드를 호출하면 this가 무엇을 가리킬지 정해줄 수 있습니다.
// 호출할 때 첫 번째 인자로 this가 가리켜야 할 객체를 넘겨줍니다.
// 그래서 monkey Function 안에서 this는 위에서 설명했던 객체 중 하나를 가리키는 것이 아니라 animal를 가리킵니다.

function monkey(a, b, c) {}

var animal = {};
monkey.apply(animal, [1, 2, 3]); // a = 1, b = 2, c = 3으로 넘어갑니다.
monkey.call(animal, 1, 2, 3); // same as


함정


this가 Global 객체를 가리키는 것도 잘못 설계된 부분 중 하나입니다. 


Monkey.method = function() {
function test() {
// 여기에서 this는 Global 객체를 가리킵니다.
}
test();
}


test에서 this가 Monkey를 가리킬 것으로 생각이 들지만 실제로는 그렇지 않습니다. test에서 Monkey에 접근하려면 method에 Local변수를 하나 만들고 Monkey를 가리키게 하여야 합니다.


Monkey.method = function() {
var self = this;

function test() {
// 여기에서 this 대신에 self를 사용하여 Monkey에 접근합니다.
}
test();
}


self는 통상적인 변수 이름이지만, 바깥쪽의 this를 참조하기 위해 일반적으로 사용됩니다. 또한, 클로저와 결합하여 this의 값을 주고받는 용도로 사용할 수도 있습니다.


Monkey.method = function() {
var test = function() {
// this는 이제 Monkey를 참조한다
}.bind(this);
test();
}


위와같이 bind 메서드를 사용하여 같은 결과를 얻을 수도 있습니다.



Method 할당하기


Javascript의 또다른 함정은 바로 함수의 별칭을 만들 수 없다는 점입니다. 별칭을 만들기 위해서 메소드를 변수에 넣으면 자바스크립트는 별칭을 만들지 않고 바로 할당해 버립니다. 


var test = someObject.methodTest;
test();


첫번째 코드로 인해 이제 test는 다른 함수와 똑같이 동작합니다. 그래서, test 함수 내부의 this도 더이상 someObject를 가리키지 않습니다. 이렇게 this를 늦게 바인딩해서 나타나는 약점 때문에 늦은 바인딩이 나쁜것이라 생각이 되어질 수도 있지만, 이런 특징으로 인해 프로토타입 상속이 가능해 집니다.


function Monkey() {}
Monkey.prototype.method = function() {};

function Animal() {}
Animal.prototype = Monkey.prototype;

new Animal().method();


Animal 인스턴스에서 method를 호출하면 method에서 this는 바로 그 인스턴스를 가리킵니다.


License

이 게시글은 JavaScript Garden을 참고하여 작성 되었습니다. (https://github.com/BonsaiDen/JavaScript-Garden)



Comments