This
This : 객체를 참조하는 키워드
this의 값은 함수를 호출한 위치에서 결정됨.
1. 단독으로 쓰인 this
•
this를 호출하는 경우엔 global object를 지침
•
브라우저에서 호출하는 경우 ⇒ [object Window]
•
ES5 strict mode(엄격 모드)에서도 마찬가지
'use strict';
let x = this;
console.log(x); //Window
JavaScript
복사
2. 함수 안에서 쓴 this
함수 안에서 this는 함수의 주인(window객체)에게 바인딩
•
느슨한 모드(sloppy mode)
function myFunction() {
return this;
}
console.log(myFunction()); //Window
let num = 0; // (전역변수)
function addNum() {
this.num = 100; // window객체
num++;
console.log(num); // 101
console.log(window.num); // 101
console.log(num === window.num); // true
}
addNum();
JavaScript
복사
•
엄격 모드(strict mode)
◦
함수 내의 this에 디폴트 바인딩이 없기 때문에 undefined
"use strict";
function myFunction() {
return this;
}
console.log(myFunction()); //undefined
let num = 0;
function addNum() {
this.num = 100; //ERROR! Cannot set property 'num' of undefined === undefined.num
num++;
}
addNum();
JavaScript
복사
3. 메서드 안에서 쓴 this
•
메서드 호출 시 메서드 내부 코드에서 사용된 this는 해당 메서드를 호출한 객체로 바인딩
let person = {
firstName: 'John',
lastName: 'Doe',
fullName: function () {
return this.firstName + ' ' + this.lastName;
},
};
person.fullName(); //"John Doe"
JavaScript
복사
•
프로그램 최상위에서 사용할 경우 var는 전역 객체에 속성을 추가하지만 let은 추가 X
let num = 0;
function showNum() {
console.log(num); // 여기서 this는 window
}
showNum(); // var일 경우 0, let일 경우 undefined
// var은 전역객체에 들어가지만 let은 전역객체에 들어가지 않는다.
// var은 전역객체, let은 전역범위
let obj = {
num: 200,
func: showNum,
};
obj.func(); // 둘다 200
JavaScript
복사
4. 이벤트 핸들러 안에서 쓴 this
•
이벤트 핸들러에서 this는 이벤트를 받는 HTML 요소로 바인딩
let btn = document.querySelector('#btn')
btn.addEventListener('click', function () {
console.log(this); //#btn
});
JavaScript
복사
5. 생성자 안에서 쓴 this
•
생성자 함수가 생성하는 객체로 this가 바인딩
function Person(name) {
this.name = name;
}
let kim = new Person('kim');
let lee = new Person('lee');
console.log(kim.name); //kim
console.log(lee.name); //lee
JavaScript
복사
•
new 키워드를 빼먹는 순간 일반 함수 호출과 같아지기 때문에, 이 경우는 this가 window에 바인딩
let name = 'window';
function Person(name) {
this.name = name;
}
let kim = Person('kim');
console.log(window.name); //kim
JavaScript
복사
6. 화살표 함수로 쓴 this
•
함수 안에서 this가 전역 객체로 안 쓰고 싶을 떄
•
화살표 함수는 전역 컨텍스트에서 실행되더라도 this를 새로 정의하지 않고, 바로 바깥 함수나 클래스의 this를 사용
let Person = function (name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(this); // Person {name: "Nana", age: 28}
setTimeout(function () {
console.log(this); // Window
console.log(this.name + ' is ' + this.age + ' years old');
}, 100);
};
};
let me = new Person('Nana', 28);
me.say(); // undefined is undefined years old
JavaScript
복사
⇒
let Person = function (name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(this); // Person {name: "Nana", age: 28}
setTimeout(() => {
console.log(this); // Person {name: "Nana", age: 28}
console.log(this.name + ' is ' + this.age + ' years old');
}, 100);
};
};
let me = new Person('Nana', 28);
me.say(); //Nana is 28 years old
JavaScript
복사
7. 명시적 바인딩을 한 this
•
명시적 바인딩 : 해당 this를 짝으로 지정하는 것
•
apply()와 call()은 보통 유사배열 객체에게 배열 메서드를 쓰고자 할 때 사용
function whoisThis() {
console.log(this);
}
whoisThis(); //window
let obj = {
x: 123,
};
whoisThis.call(obj); //{x:123}
JavaScript
복사
•
apply() 활용 1 ⇒ 2
function Character(name, level) {
this.name = name;
this.level = level;
}
function Player(name, level, job) {
this.name = name;
this.level = level;
this.job = job;
}
JavaScript
복사
function Character(name, level) {
this.name = name;
this.level = level;
}
function Player(name, level, job) {
Character.apply(this, [name, level]);
this.job = job;
}
let me = new Player('Nana', 10, 'Magician');
JavaScript
복사
call and apply
function add(a, b) {
return a + b;
}
console.log(add.call(null, 1, 2)); // 3
console.log(add.apply(null, [1, 2])); // 3
JavaScript
복사