메소드 안에서의 this
객체가 가지고 있는 함수를 메소드(Method)라고 하는데
function beaver() {
console.log(this);
};
위와같이 전역 함수를 선언하면 그냥 함수가 허공에 만들어진다고 생각될 수 있겠지만
실제로는 전역 객체(window 혹은 global) 안에 함수가 선언되는 것이기 때문에
전역 함수도 결국에는 메소드이다.
이 beaver 함수를 호출해서 this가 무엇이 호출되었는지 확인하면 전역 객체인 Window 가 출력됩니다. 이 결과로 메소드를 호출할 시 메소드 안에서 this는 함수를 소유하고 있는 객체가 된다는 것을 알 수 있다.
그렇다면 beaver가 this가 되는 경우는 사용자가 직접 객체 안에서 메소드를 만들때이다
예를 들면
var beaver = {
foo : function() {
console.log(this);
}
}
beaver.foo(); // 여기서 this 는 beaver가 된다.
+beaver가 this여서 foo 객체가 출력된것이다 다음 코드를 보면 이해가 더 쉽다.
메소드가 아닌 독립적인 함수 안에서의 this
항상 함수가 객체 안에서만 선언되는 것은 아니다.
예를들어 다음과 같이 함수 안에 함수가 선언되는 경우를 많이 볼 수 있다.
beaver 전역 함수 안에 raccon 이라는 함수를 선언해 호출할때 이 경우 특정 객체에 함수를 선언한 것이 아닌
독립적인 함수로 인식되기때문에 이 함수의 경우 this 는 전역객체가 된다.
생성자로 인해 호출된 this
function Beaver(name) {
this.name = name;
}
Beaver("foo");
console.log(window.name); // "foo"
위 함수에서의 this 는 전역객체가 되기 때문에 Baver 함수 호출 후 window.name을 호출했을 때 "foo" 가 출력됨
추가적으로 함수를 new 연산자를 통해서 생성자로 호출하는 경우에는 this가 똑같이 전역 객체를 가리키지는 않는다.
function Beaver(name) {
this.name = name;
}
var foo = new Beaver("foo"); // 이 생성자로 만들어진 객체 this 를 반환
var bar = new Beaver("bar"); // 이 생성자로 만들어진 객체 this 를 반환
console.log(window.name); // 빈 문자열 "" 이 출력
console.log(foo.name); // "foo"
console.log(bar.name); // "bar"
new 로 인해서 함수를 생성자로 호출하는 경우에는 함수 안에서 this가 새롭게 만들어진 객체를 가리키게 되고
위 코드에서 window.name 을 출력해도 빈 문자열이 출력됩니다.
new 연산자로 호출한 함수 생성자는 반환할 때 자기 자신(this) 를 반환하기 때문에 그 값을 각각 변수에 넣어 name 프로퍼티를 출력했을 때 해당 객체의 name에 접근할 수 있다.
화살표 함수 안에서의 this
원래대로 라면 메소드로 호출된 beaver.foo 함수의 결과는 함수를 소유하고있는 beaver가 this가 되어야 한다.
하지만 화살표 함수는 함수를 호출하는 영역의 this 를 그대로 가져온다
위 예제에서는 함수를 호출한 영역이 전역(즉, window) 객체이기 때문에 this 가 전역객체가 됩니다.
this 정해주기 (call, apply, bind)
function foo() {
console.log(this.name);
}
var beaver = {
name : "dorothy"
};
foo.call(beaver); // "dorothy"
위 예제에서 foo 함수를 호출하면 this 는 전역객체가 되어야 겠지만
call (혹은 apply) 를 이용해서 함수를 호출하게 되면 매개변수로 함수 안에서의 this를 지정할 수 있다.
기본적으로 call 과 apply 는 완전히 동일한 결과를 가지는 함수지만 사용하는 방법에서 차이가 있습니다.
function profile(age, weight) {
console.log(this.name);
console.log("age : " + age);
console.log("weight : " + weight);
}
var beaver = {
name : "dorothy"
};
profile.apply(beaver, [4, "2kg"]);
//profile.call(beaver, 4, "2kg");
위 예제에서 apply 와 call 을 호출한 부분을 살펴보면
apply 는 두번째 매개변수([4, "2kg"])에 배열로 값을 묶어서 전달했지만
call 은 하나하나 값을 따로 전달해서 호출합니다.
즉, 함수를 호출할 때 매개변수로 전달할 값들을 배열로 묶어서 전달할지,
아니면 따로 하나하나 값을 넣어서 전달할지의 차이입니다.
function profile(age, weight) {
console.log(this.name);
console.log("age : " + age);
console.log("weight : " + weight);
}
var beaver = {
name : "dorothy"
};
profile.bind(beaver)(4, "2kg");
마지막으로 bind 를 사용해서도 this를 변경할 수 있음을 예제로 보여줍니다.
다만, bind의 경우 커링(currying) 에 대한 이해가 있어야 동작 방식을 이해하실 수 있습니다.
출처:https://mynameisdabin.tistory.com/8?category=786517
'웹 개념 > javascript' 카테고리의 다른 글
커링(currying) (0) | 2022.04.20 |
---|---|
|| 개념 (0) | 2022.04.20 |
생성자와 new 연산자 (0) | 2022.04.20 |
foreach 문 (0) | 2021.11.27 |
객체 리터럴 (0) | 2021.11.27 |