객체는 실제 존재하는 개체(entity)를 표현하고자 할 때 생성된다.
let user = {
name: "John",
age: 30
};
위와 같은 객체가 있다고 가정하면, 자바스크립트에서는 객체의 프로퍼티에 함수를 할당하여, 객체에게 행동할 수 있는 능력을 부여해준다.
let user = {
name: "John",
age: 30
};
user.sayHi = function() {
alert("Hello");
};
user.sayHi(); // Hello
위의 코드를 살펴보면 함수 표현식으로 함수를 만들고, 객체 프로퍼티 user.sayHi
에 함수를 할당해 주었다.
이제 객체에 할당된 함수를 호출하면 user가 'Hello'라는 응답을 한다.
이렇게 객체 프로퍼티에 할당된 함수를 메서드(method)
라고 부른다.
위의 코드에서는 user
에 할당된 sayHi
가 메서드이다.
또 메서드는 이미 정의된 함수를 이용해서 만들 수도 있다.
아래의 코드를 보자.
let user = {
name: "John",
age: 30
};
// 함수 선언
function sayHi() {
alert('Hello');
}
// 선언된 함수를 메서드로 등록
user.sayHi = sayHi;
user.sayHi(); // Hello
🧐객체 지향 프로그래밍
객체를 사용하여 개체를 표현하는 방식
을 객체 지향 프로그래밍(object-oriented programming, OOP) 이라 부른다.
OOP는 그 자체만으로도 학문의 분야를 만드는 중요한 주제이다. 올바른 개체를 선택하는 방법, 개체 사이의 상호작용을 나타내는 방법 등에 관한 의사결정은 객체 지향 설계를 기반으로 이뤄진다.
메서드는 객체에 저장된 정보에 접근할 수 있어야 제 역할을 할 수 있다. 모든 메서드가 그런건 아니지만, 대부분의 메서드가 객체 프로퍼티의 값을 활용한다.
메서드 내부에서 this
키워드를 사용하면 객체에 접근할 수 있다.
let user = {
name: "John",
age: 30,
sayHi() {
// this 는 '현재 객체'를 나타낸다.
alert(this.name);
}
};
user.sayHi(); // John
user.sayHi()
가 실행되는 동안에 this
는 user
를 나타낸다.
this
를 사용하지 않고 외부 변수를 참조해 객체에 접근하는 것도 가능하다.
let user = {
name: "John",
age: 30
sayHi() {
alert(user.name); // 'this' 대신 'user'를 이용함
}
};
이렇게 외부 변수를 사용해 객체를 참조하면 예상치 못한 에러가 발생할 수 있다. user
를 복사해 다른 변수에 할당하고, user
는 전혀 다른 값으로 덮어썼다고 가정해 보자. sayHi()
는 원치 않는 값(null)을 참조할 것이다.
let user = {
name: "John",
age: 30
sayHi() {
alert(user.name); // Error: Cannot read property 'name' of null
}
};
let admin = user;
user = null; // user를 null로 덮어쓴다.
admin.sayHi(); // sayHi()가 엉뚱한 객체를 참조하면서 에러가 발생
여기에서 alert
함수가 user.name
대신 this.name
을 인수로 받았다면 에러가 발생하지 않았을 것이다.
자바스크립트의 this
는 다른 프로그래밍 언어의 this
와 동작 방식이 다르다. 자바스크립트에서는 모든 함수에 this
를 사용할 수 있다.
function sayHi() {
alert(this.name);
}
이렇게 코드를 작성해도 문법 에러가 발생하지 않는다.
this
값은 런타임에 결정된다. 컨텍스트에 따라 달라지는 것이다.
동일한 함수라도 다른 객체에서 호출했다면 'this'가 참조하는 값이 달라진다.
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
alert(this.name);
}
// 별개의 객체에서 동일한 함수를 사용함
user.f = sayHi;
admin.f = sayHi;
user.f(); // John (this === user)
admin.f(); // Admin (this === admin)
admin['f'](); // Admin (점과 대괄호는 동일하게 동작)
규칙은 간단하다. obj.f()
를 호출했다면 this
는 f
를 호출하는 동안의 obj
이다. 위 예시에서는 obj
가 user
나 admin
을 참조하는 것이다.
화살표 함수는 일반 함수와는 달리 고유한 this
를 가지지 않는다. 화살표 함수에서 this
를 참조하면, 화살표 함수가 아닌 평범한 외부 함수에서 this
값을 가져온다.
let user = {
firstName: "Kevin",
sayHi() {
let arrow = () => alert(this.firstName);
arrow();
}
};
user.sayHi(); // Kevin
별개의 this
가 만들어지는 건 원하지 않고, 외부 컨텍스트에 있는 this
를 이용하고 싶은 경우 화살표 함수가 유용하다.