자바스크립트 내에서 ‘this’는 ‘누가 나를 불렀느냐’ 를 뜻한다. 즉, 선언이 아닌 호출에 따라 달라진다.
단독으로 this를 호출하는 경우엔 global object(전역 객체, 즉 window)를 가리킨다.
var num = 0;
function addNum() {
this.num = 100;
num++;
console.log(num); // 101
console.log(window.num); // 101
console.log(num === window.num); // true
}
addNum();
함수 안에서 this는 함수의 주인에게 바인딩한다. 위 코드에서 this.num의 this는 window 객체를 가리킨다.
따라서 num은 전역 변수를 가리키게 된다. 다만 엄격 모드에서는 함수 내의 this에 디폴트 바인딩이 없기 때문에 undefinde가 뜬다.
"use strict";
function myFunction() {
return this;
}
console.log(myFunction()); //undefined
const cat = {
name : '방울',
age: 4,
color: 'white',
meow : function(){
console.log(this.name + ' : 야옹')
}}
cat.meow() // 방울 : 야옹
일반 함수가 아닌 메서드의 경우, 메서드 호출 시 메서드 내부 코드에서 사용된 this는 해당 메서드를 호출한 객체로 바인딩됩니다.
function Cat(name) {
this.name = name;
}
const bangul = new Cat('방울');
const cheese = new Cat('치즈');
console.log(bangul.name); // 방울
console.log(cheese.name); // 치즈
생성자 함수가 생성하는 객체로 this 가 바인딩된다.
하지만 new
키워드를 빼먹는 순간 일반 함수 호출과 같아지기 때문에, 이 경우는 this가 window에 바인딩된다.
function Cat(name) {
this.name = name;
}
const kkomi = Cat('꼬미');
undefined
console.log(kkomi.name); // Uncaught TypeError: Cannot read properties of undefined (reading 'name')
console.log(window.name) // 꼬미
이벤트 핸들러에서 this는 이벤트를 받는 HTML 요소를 가리킨다.
const hd = document.querySelector('#header')
hd.addEventListener('click', function () {
console.log(this); //#hd
});
apply()
, call()
등 Function Object 에 기본적으로 정의된 메서드가 있다. 이들은 인자를 this로 만들어 주는 기능을 한다.
function whoisThis() {
console.log(this);
}
whoisThis(); //window
const obj = {
x: 123,
};
whoisThis.call(obj); //{x:123}
apply()
에서 매개변수로 받은 첫 번째 값은 함수 내부에서 사용되는 this
에 바인딩되고, 두 번째 값인 배열은 자신을 호출한 함수의 인자로 사용한다.
두 메서드의 기능은 거의 같으나 call()
은 인수의 목록을 받고 apply()
는 인수 배열을 받는다는 차이가 있다.
function Character(name, level) {
this.name = name;
this.level = level;
}
function Player(name, level, job) {
Character.apply(this, [name, level]); //Character.call(this, name, level);
this.job = job;
}
const me = new Player('Bangul', 10, 'Cat');
화살표 함수는 전역 컨텍스트에서 실행되더라도 this를 새로 정의하지 않고, 바로 바깥 함수나 클래스의 this를 사용한다.
const Person = function (name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(this);
setTimeout(() => {
console.log(this);
console.log(this.name + ' is ' + this.age + ' years old');
}, 100);
};
};
const me = new Person('방울', 4); // 방울 is 4 years old
me.say();
setTimeout(function () {
console.log(this); // Window
console.log(this.name + ' is ' + this.age + ' years old');
}, 100);
const me = new Person('방울', 4);
me.say(); //global is undefined years old
일반 함수를 사용했을 경우 내부 함수의 this가 전역 객체를 가리켜서 의도와는 다른 결과가 나온다. 화살표 함수를 사용하면 이 문제를 해결할 수 있다.