메서드와 this 파트 링크 : https://ko.javascript.info/object-methods
<script>
let user = {
name: "John",
age: 30
};
user.sayHi = function() {
alert("안녕하세요!");
};
user.sayHi(); // 안녕하세요!
</script>
위처럼 객체의 프로퍼티에 할당된 함수를 메서드라고 한다.
또 프로퍼티에 바로 함수를 선언하는 방법 외에 이미 선언된 함수를 프로퍼티에 할당하는 방법도 있다.
<script>
let user = {
// ...
};
// 함수 선언
function sayHi() {
alert("안녕하세요!");
};
// 선언된 함수를 메서드로 등록
user.sayHi = sayHi;
user.sayHi(); // 안녕하세요!
</script>
<script>
// 아래 두 객체는 동일하게 동작한다.
// (객체 상속 관련 차이가 있지만 나중에 다룬다고 한다.)
user = {
sayHi: function() {
alert("Hello");
}
};
// 단축 구문
user = {
sayHi() { // "sayHi: function()"과 동일
alert("Hello");
}
};
</script>
메서드 내부에서 this 키워드를 사용하면 객체에 접근할 수 있습니다.
this.~ 에서 점 앞의 this는 메서드를 호출할 때 사용된 객체를 나타낸다.
<script>
let user = {
name: "John",
age: 30,
sayHi() {
// 'this'는 '현재 객체'를 나타냅니다.
alert(this.name);
}
};
user.sayHi(); // John
//-----------------------------------------
let user = {
name: "John",
age: 30,
sayHi() {
alert(user.name); // 'this' 대신 외부변수 'user'를 이용하는 것도 가능
}
};
</script>
하지만 외부변수를 사용하면 원하는 값과 다른 값을 얻을 위험이 있다.
예를들면 외부변수 user에 전혀 다른 값을 덮어씌웠을 경우... 우리가 기대한 값과는 전혀 다른 값을 얻게된다. (변수의 값은 종종 다른 값으로 바뀔 수 있으니까)
<script>
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()가 엉뚱한 객체를 참고하면서 에러가 발생
</script>
자바스크립트는 다른 언어와 다르게 모든 함수에 this를 사용할 수 있다.
이때 this의 값은 런타임에 의해 결정되고 컨텍스트에 따라 달라진다.
<script>
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
alert( this.name );
}
// 별개의 객체에서 동일한 함수를 사용함
user.f = sayHi;
admin.f = sayHi;
// 'this'는 '점(.) 앞의' 객체를 참조하기 때문에
// this 값이 달라짐
user.f(); // John (this == user)
admin.f(); // Admin (this == admin)
admin['f'](); // Admin (점과 대괄호는 동일하게 동작함)
</script>
this의 값이 런타임에 결정되기 때문에 this의 값은 반드시 객체를 가리킨다고 특정할 수 없다.
엄격 모드가 아닐 때는 this가 전역 객체를 참조한다. 브라우저 환경에선 window라는 전역 객체를 참조한다. 이런 동작 차이는 "use strict"가 도입된 배경이기도 하다.
화살표 함수는 일반 함수와는 달리 ‘고유한’ this를 가지지 않는다.
화살표 함수에서 this를 참조하면, 화살표 함수가 아닌 다른 평범한 외부 함수에서 this 값을 가져온다.
아래는 복습 코드 중 정답을 틀린 코드다.
나중에 봐도 헷갈릴 것이 분명해보인다.
<script>
function makeUser() {
return {
name: "John",
ref: this
};
};
let user = makeUser();
alert( user.ref.name ); // Error: Cannot read property 'name' of undefined
</script>
this는 호출 시점에 결정되는데 makeUser()가 메서드로써 호출된 게 아니라 함수로써 호출됐기 때문에 property 값인 this는 makeUser를 참조하지 못하고 undefined를 뱉는다.
<script>
function makeUser() {
return {
name: "John",
ref() {
return this;
}
};
};
let user = makeUser();
alert( user.ref().name ); // John
</script>
위와같이 코드를 수정하면 user.ref()가 메서드가 되고 this는 . 앞의 객체가 되어 해당 객체를 정상적으로 잘 참조한다!!