자바스크립트로 코딩을하면서, this란 것이 정확하게 무엇을 가리키는게 무엇인지 이해하기 어려운 경우가 생기게 됩니다. 그 이유는 this가 사용하는 방식에 따라 가리키는 대상이 달라서 입니다. 오늘은 상황별 this가 가리키는 대상과 binding하는 방법에 대해서 정리하고자 합니다.
우선 this는 사용되는 경우에 따라 다른 값을 가리킵니다.
위의 설명만으로는 잘 이해가 되지 않아 직접 코딩을 하며 this가 가리키는 것을 확인해 보았다.
전역 스코프에서 console.log를 통해 tihs가 가리키는 값을 찾아본 결과, this.age는 'undefined'가 출력되고 this.alert 값이 출력되는 것을 보아 this가 가리키는 것이 window임을 알 수 있습니다.
const cat = {
name : '꼬미',
age : 5,
say : function cry() {
console.log(`MEOW!! 내 나이는 ${this.age}살이야`);
}
}
console.log(this.age); // undefined
console.log(this.alert); // ƒ alert() { [native code] }
함수 내부의에서 this가 window를 가리키는지 확인하기 위해 프로퍼티 alert가 제대로 출력되는지 확인한 결과 this는 window임을 알 수 있습니다.
function foo() {
console.log(this.alert); // this가 window를 가리키는지 검증
}
foo() // ƒ alert() { [native code] }
아래의 코드를 보면 cat 객체에 call에 내부 메소드를 선언하고 메소드 호출을 하면 this.age는 'undefined' 값이 출력됩니다.
const cat = {
name : '꼬미',
age : 5,
say : function () {
function cry() {
console.log(`MEOW!! 내 나이는 ${this.age}살이야`);
console.log(this.alert); // this가 window를 가리키는지 검증
}
cry()
}
}
cat.say() // MEOW!! 내 나이는 undefined살이야
// ƒ alert() { [native code] }
아래의 코드를 보면 cat 객체에 call에 메소드를 선언하고 메소드 호출을 통해 this.age 값을 출력합니다. 여기서 this는 객체 cat을 가리키는 것을 알 수 있습니다.
const cat = {
name : '꼬미',
age : 5,
say: function cry() {
console.log(`MEOW!! 내 나이는 ${this.age}살이야`);
}
}
cat.say() // MEOW!! 내 나이는 5살이야
name 값을 받아 객체를 생성하는 생성자 함수를 선언 할 때 this를 사용했습니다. 여기서 this는 new 키워드로 생성한 cat이라는 객체를 가리키는 것을 알 수 있습니다.
function Cat(name) {
this.name = name;
this.isAdmin = false;
}
let cat = new Cat("꼬미");
console.log(cat.name); // 꼬미
위에서 객체의 속한 메소드의 내부함수에서 this는 전역 객체(window)를 가리킨다는 것을 알 수 있었습니다. 그러나 메소드의 내부함수에서 화살표 함수를 사용하면 this가 가리키는 대상은 cat 객체가 됩니다. 이런 현상이 발생하는 이유는 화살표 함수가 선언되는 순간 상위 환경의 this를 참조하기 때문입니다.
const cat = {
name : '꼬미',
age : 5,
say : function() {
let sayage = () => {
console.log(`MEOW!! 내 나이는 ${this.age}살이야`);
}
sayage();
}
}
cat.say(); // MEOW!! 내 나이는 5살이야
addEventListener의 콜백함수에서는 this에 해당 이벤트 리스너가 호출된 엘리먼트가 바인딩되도록 정의되어 있습니다. 이처럼 this값이 정해져있는 콜백함수의 경우 화살표 함수를 사용하면 기존 바이딩값이 사라지므로 조심해서 사용해야합니다.
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
console.log(this); // Window
this.innerHTML = 'clicked';
});
button.addEventListener('click', function() {
console.log(this); // button 엘리먼트
this.innerHTML = 'clicked';
});
함수 호출 방식과 관계 없이 this 값을 지정해 주는 방법이 있습니다. 바로 call, apply, Bind 메소드를 사용하는 것 입니다.
모든 함수에서 사용할 수 있으며, this값을 특정값으로 지정할 수 있습니다.
const ggom = {
name : '꼬미'
}
const ratte = {
name : '라떼'
}
function sayName() {
console.log(this.name);
}
sayName()
sayName.call(ggom); // 꼬미
sayName.call(ratte); // 라떼
function update(age, hooby) {
this.age = age;
this.hobby = hobby;
}
update.call(ggom, 4, '공놀이');
console.log(ggom);
// {name: "꼬미", age : 4, hooby: '공놀이'}
update.call(ratte, 3, '꾹꾹이');
console.log(ratte);
// {name: "라떼", age : 3, hooby: '꾹꾹이'}
위의 코드에서 보면 sayName이라는 함수에 call 메서드를 통해서 객체를 전달인자로 받아 함수의 매개변수로 전달합니다. 함수를 실행시켜 this가 보면 전달한 객체를 가리키는 것을 알 수 있습니다.
또한, 첫 번째 매개변수로 객체를 받아 this값을 지정해주고 두 번째 매개변수 부터는 객체의 값을 변경하는데 사용됩니다.
apply 메소드는 매개변수를 직접 받는 call과 다르게 매개변수로 전달할 데이터를 포함하는 배열은 전달하고 전달된 배열의 요소들을 차례대로 매개변수로 사용합니다.
const ggom = {
name : '꼬미'
}
const ratte = {
name : '라떼'
}
function update(age, hooby) {
this.age = age;
this.hobby = hobby;
}
update.apply(ggom, [4, '공놀이']);
console.log(ggom);
// {name: "꼬미", age : 4, hooby: '공놀이'}
update.apply(ratte, [3, '꾹꾹이']);
console.log(ratte);
// {name: "라떼", age : 3, hooby: '꾹꾹이'}
bind를 사용하면 함수의 this값을 영구적으로 변경이 가능합니다.
const ggom = {
name : '꼬미'
}
function update(age, hooby) {
this.age = age;
this.hobby = hobby;
}
const updateggom = update.bind(ggom);
updateggom(3, '공놀이');
console.log(ggom);
// {name: "꼬미", age : 4, hooby: '공놀이'}
refenrence : https://sangjuntech.tistory.com/24
https://velog.io/@padoling/JavaScrip