함수를 호출하는 객체
대부분의 경우 this의 값은 함수를 호출한 방법에 의해 결정
현재 속해있는 객체를 가리킨다?!
자신을 호출하는 것을 참조한다
https://ko.javascript.info/strict-mode
엄격모드와 비엄격모드에서 차이가 있다
엄격모드 할 거면 최상단에 'use strict' 달고 전체적으로 사용하기 (함수별로 사용하면 혼란이 있을 수 있어서)
왜 쓰지?
let myDinner = {
name: "김치찌개",
menu: function(){
console.log("오늘 저녁은 " + myDinner.name);
}
}
myDinner.menu();
// 오늘 저녁은 김치찌개
이런 객체가 있을 때 menu 함수는
myDinner 변수 이름이 수정될 경우,
menu 함수 자체를 다른 객체에서 사용하고 싶은 경우에
사용이 불편해진다
그렇다면?
function menuGlobal() {
console.log("오늘 저녁은 " + this.name);
}
let myDinner = {
name : "김치찌개",
menu : menuGlobal
}
myDinner.menu()
// 오늘 저녁은 김치찌개
let yourDinner = {
name : "된장찌개",
menu : menuGlobal
}
yourDinner.menu()
// 오늘 저녁은 된장찌개
this를 이용하면 global하게 다른 객체에서도 재사용할 수 있다!
this 값은 자동으로 할당되지만, 상황에 따라 제어할 수 있어야 한다
this 값을 바꿀 수도 있고 함수 실행할 때 사용할 인수도 전달할 수 있다
function menuGlobal(item){
console.log("오늘 저녁은 " + item + this.name)
}
let myDinner = {
name : "김치찌개"
}
let yourDinner = {
name : "된장찌개"
}
menuGlobal.call(myDinner, "묵은지");
// 오늘 저녁은 묵은지김치찌개
menuGlobal.call(yourDinner, "호박");
//오늘 저녁은 호박된장찌개
함수에서 바라볼 객체를 적어주고(myDinner) 인자값 전달("묵은지")
menuGlobal 함수가 실행됐을 때
myDinner를 바라보게 되고(this.name에서 this는 myDinner 객체)
이 객체 키값인 김치찌개를 가져온다
item은 묵은지
함수를 실행할 때 인수를 배열에 묶어 한번에 전달
function menuGlobal(item1, item2) {
[item1, item2].forEach(function(el){
console.log("오늘 저녁은 " + el + this.name)
}, this);
}
let myDinner = {
name: "김치찌개"
}
let yourDinner = {
name: "된장찌개"
}
menuGlobal.apply(myDinner, ["묵은지","참치"]);
//
오늘 저녁은 묵은지김치찌개
오늘 저녁은 참치김치찌개
menuGlobal.apply(yourDinner, ["두부","호박"]);
//
오늘 저녁은 두부된장찌개
오늘 저녁은 호박된장찌개
인수로 전달할 배열 안에 원소 2개 item2, item2(인자)를 만들었다
전달받을 배열 [item1, item2]를 forEach문으로 돌려보자
forEach 안에서 this를 전달받으려면 forEach 함수의 두번째 인자로 this를 선언해줘야 함
선언하지 않으면 forEach 안에 this는 그 안에서 함수를 실행하는 객체를 바라보게 되는데 그 객체는 window 객체
자동으로 자신을 호출하는 객체가 this 안으로 할당되기 때문에 forEach문 안에서 this 값을 지정해주지 않는 이상 항상 전역객체를 바라보게 된다
그래서 forEach(function(el){},this) <- this라고 선언하게 되는데 이건 상위스코프의 this를 바라보게 된다
이제 메뉴글로벌 함수에 어플라이 함수 실행! 첫번째 인수로 this를 지정할 객체를 지정, 전달할 인수가 배열... forEach문이 돌아가면서 배열 원소가 2개니까 2번 실행
call : 함수 실행할 때 전달할 인수를 하나하나 전덜
appy : 전달할 인수를 배열로 묶어 한번에 전달, 그래서 인수를 두 개만 사용
인수를 배열로 보낸다는 점 빼고 동일한 기능 수행
ES5에서 추가
this값을 어디서 사용하든 호출 객체가 바뀌지 않게 고정시킴
this에 할당되는 객체가 고정된 새로운 함수 생성
function menuGlobal(item){
console.log("오늘 저녁은 " + item + this.name)
}
let myDinner = {
name : "김치찌개"
}
let yourDinner = {
name : "된장찌개"
}
let menuGlobalForMe = menuGlobal.bind(myDinner);
console.log(menuGlobalForMe("묵은지"));
// 오늘 저녁은 묵은지김치찌개
let menuGlobalForYou = menuGlobal.bind(yourDinner);
console.log(menuGlobalForYou("두부"));
// 오늘 저녁은 두부된장찌개
메뉴글로벌 함수의 바인드 메소드 실행! bind의 인수에는 this를 지정할 객체를 지정(myDinner)
메뉴글로벌 함수가 바라보는 객체가 마이디너로 고정된 새로운 함수가 메뉴글로벌포미에 들어간다
메뉴글로벌포미는 다른 새로운 함수 이 함수의 전달 인자로 "묵은지" 지정~
function menuGlobal(item){
console.log("오늘 저녁은 " + item + this.name)
}
let myDinner = {
name : "김치찌개"
menuMine : menuGlobaForyou
}
let yourDinner = {
name : "된장찌개"
}
let menuGlobalForMe = menuGlobal.bind(myDinner);
console.log(menuGlobalForMe("묵은지"));
// 오늘 저녁은 묵은지김치찌개
let menuGlobalForYou = menuGlobal.bind(yourDinner);
console.log(menuGlobalForYou("두부"));
// 오늘 저녁은 두부된장찌개
myDinner.menuMine = menuGlobalForYou;
myDinner.menuMine("묵은지");
// 오늘 저녁은 묵은지된장찌개
myDinner 라는 객체에 새로운 키(menuMine)를 부여하고, 그 키의 값은menuGlobalForYou
let myDinner = { name : "김치찌개" menuMine : menuGlobaForyou }
와 같다
"묵은지"를 인수로 전달하는 myDinner.menuMine("묵은지");
함수를 실행하면 어떻게 될까?
let menuGlobalForYou = menuGlobal.bind(yourDinner);
menuGlobalForYou는 menuGlobal 함수인데 bind 메소드를 이용해 객체를 yourDinner로 고정했다
myDinner.menuMine("묵은지");
myDinner에서 사용하는데 이 함수가 바라보는 객체는 yourDinner가 될 것이다
... 오늘 저녁은 묵은지된장찌개!
다른 객체에서 실행되는 함수도 그 함수가 바라보는 객체를 고정시켜버릴 수 있다
화살표 함수의 this는 상위 스코프의 this, 상위 스코프의 객체를 할당 받는다
자신을 둘러싸고 있는 부모를!
function menuGlobal(item1, item2) {
[item1, item2].forEach(function(el){
console.log("오늘 저녁은 " + el + this.name)
}, this);
}
여기서 forEach에서 두번째 인수로 this를 사용. (this를 사용하지 않으면 forEach 안에 있던 this(this.name)가 자동으로 자신을 호출)
화살표 함수를 쓴다면? function 지우고 두번째 this 지우고
function menuGlobal(item1, item2) {
console.log(this);
[item1, item2].forEach((el) => {
console.log("오늘 저녁은 " + el + this.name)
});
}
let myDinner = {
name: "김치찌개"
}
menuGlobal.apply(myDinner, ["묵은지","참치"]);
//
{name: '김치찌개'} [[prototype]]: object
오늘 저녁은 묵은지김치찌개
오늘 저녁은 참치김치찌개
forEach문 위에console.log(this);
찍어보면 forEach문의 상위스코프 this는 myDinner