[모던 JavaScript 튜토리얼] 15. 메서드와 this
함수와 메서드의 차이
함수는 메서드를 포함한다고 볼 수 있다. 다시 말해, 함수가 더 큰 범주에 있고 메서드는 특징적인 함수라고 말할 수 있다. 여기서 말하는 특징은 객체에 종속적이라는 것이다. 메서드는 객체 프로퍼티에 할당된 함수다.
함수는 독립적으로 정의되므로 이름으로만 호출이 가능하다. 하지만, 메서드는 함수 이름만으로 호출되지 못한다. 정의된 객체에 의해 .(dot)으로 접근해 호출해야 한다.
자바는 모든 것이 클래스로 정의되므로 사용한 함수는 다 메서드로 불렸다. 자바스크립트에선 전역 위치에 함수가 존재할 수 있으므로, 함수와 메서드를 구분지어야 할 것 같다.
this
메서드는 위에서 봤듯이 객체에 종속적이니까, 객체에 저장된 정보에 접근할 수 있어야 제 역할을 할 수 있다. 객체에 저장된 정보를 접근할 수 있도록 도와주는 것이 this 키워드다. this 를 이용하면 객체에 접근할 수 있다. 이 때, this 는 메서드가 프로퍼티로써 정의된 객체를 의미한다.
let user = {
name: "John",
age: 30,
sayHi() {
console.log(this.name);
},
};
user.sayHi(); // John
객체 프로퍼티의 하나로 정의된 sayHi 메서드는 내부에서 this 로 객체 내부 정보를 접근한다. 위에선 this.name
을 통해 name 이란 변수에 저장된 값을 접근한다.
let user = {
name: "John",
age: 30,
sayHi() {
console.log(user.name); // Error: Cannot read property 'name' of null
},
};
let admin = user;
user = null;
admin.sayHi();
this 대신 객체의 이름 user 를 통해서 접근할 수도 있다. 하지만, user 객체가 위와 같이 null 로 초기화 된다면 값을 읽을 수 없게 될 것이다.
다양한 객체에 바인딩 해보자
this
값은 런타임에 결정된다. 컨텍스트, 즉 현재 문맥에 따라 달라진다.
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
console.log(this.name);
}
user.f = sayHi;
admin.f = sayHi;
user.f(); // John (this == user)
admin.f(); // Admin (this == admin)
admin["f"](); // Admin (점과 대괄호는 동일하게 동작함)
위 예제에서 sayHi 라는 함수를 하나 설정해뒀다. 그리고, 이 함수를 객체 내부 프로퍼티로써 저장하면서 메서드로 사용하려고 한다.
user.f();
에서 this 는 user 객체 에 바인딩되고, admin.f();
에서 this 는 admin 객체에 바인딩된다. sayHi 함수는 내부에서 this 를 접근하며, 해당 this 는 메소드로써 저장된 곳의 객체를 가리킬 것이므로, 각자의 이름이 콘솔에 찍히게 된다.
맨 밑에 admin["f"]();
는 메서드도 하나의 키-값 프로퍼티이므로, 대괄호를 사용해 값(여기선 메서드)를 접근한 뒤, 소괄호로 호출을 하는 모습을 보여준다.
객체 없이 this 호출하기
function sayHi() {
console.log(this);
}
sayHi();
위 코드를 브라우저와 Node 환경 각각에서 실행시키면 아래와 같은 결과를 볼 수 있다.
위는 브라우저에서 실행시킨 결과다. this 는 window 라는 전역 객체를 참조하고 있다.
위는 Node 환경에서 실행시킨 결과다. this 는 global 이라는 전역 객체를 참조한다. 참고로, Node는 브라우저 환경이 아니므로, 웹 브라우저에서 사용 가능한 window 객체가 존재하지 않는다.
이 외의 다른 this 용법은 링크에 작성되어 있다.
댓글남기기