melius
[JS] this 본문
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
https://www.w3schools.com/js/js_this.asp
함수 호출시에 this가 함수 내부로 전달되는데, 호출 패턴에 따라 this는 다른 객체를 참조한다.
* 화살표 함수는 일반함수와 달리 this는 특정 객체와 바인딩이 없고, 일반 변수와 동일하게 행동한다(즉, 상위 스코프의 this).
1. 함수 호출
함수가 단독으로 호출되면 this는 전역 객체를 참조한다.
1) Browser
console.log(this); // window
var go = function () {
console.log(this, this.name);
}
var name = 'volkswagen';
console.log(name == window.name); // true
go(); // window, volkswagen
2) Node.js
console.log(this); // Object {}
this.car = 'tesla';
console.log(this); // Object {car: "tesla"}
console.log(this == exports); // true
console.log(this == module.exports); // true
var that = this;
global.car = 'volkswagen';
var car = 'honda';
console.log(this.car); // tesla
console.log(global.car); // volkswagen
console.log(car); // honda
function go() {
console.log(this); // global
console.log(this.car, car); // volkswagen honda
console.log(that == this); // false
}
go();
화살표 함수의 this는 상위 스코프의 this이다.
global.car = 'volkswagen';
var car = 'honda';
this.car = 'tesla';
var that = this;
var go = () => {
console.log(this); // Object {car: "tesla"}
console.log(this.car, car); // tesla honda
console.log(that == this); // true
}
go();
2. 객체 메소드 호출
객체의 메소드를 호출할 때, 메소드 내의 this는 호출한 객체를 참조한다.
this.name = "volkswagen";
var car = {
name: 'tesla',
ride: function () { console.log(this.name); },
move: () => { console.log(this.name); }
};
car.ride(); // tesla
car.move(); // volkswagen
3. 객체 생성자 함수 호출
new 연산자를 사용하여 함수를 객체 생성자 함수로서 호출하면 this는 생성될 인스턴스를 참조한다.
function Car() {
this.company = 'volkswagen';
// return this; // optional
}
var car = new Car();
console.log(car.company); // volkswagen
console.log(car.__proto__ == Car.prototype); // true
var Obj = () => {};
// var obj = new Obj(); // TypeError: Obj is not a constructor
* 객체 생성자 함수의 return 문에 다른 객체가 반환되는 경우에는 new 연산자를 사용해도 해당 객체를 반환된다.
4. apply, call 그리고 bind 메소드
위에서 언급한 방법들은 자바스크립트 엔진에서 자동으로 this의 참조값을 정해준다(implicit binding).
개발자가 직접 this의 참조값을 정하기(explicit binding) 위해서는 Function.prototype 객체의 프로퍼티인 apply나 call 또는 bind 메소드를 사용하면 된다.
maker = 'Apple';
model = 'iPhone';
function phone(maker, model) {
console.log(`${this.maker} - ${this.model}`);
}
var phone1 = { maker: 'Samsung', model: 'Galaxy'} ;
var phone2 = { maker: 'LG', model: 'ThinQ' };
var phone3 = { maker: 'Xiaomi', model: 'Redmi' };
phone(); // Apple - iPhone
phone.apply(phone1); // Samsung - Galaxy
phone.call(phone2); // LG - ThinQ
// bind method return function
phone.bind(phone3)(); // Xiaomi - Redmi
function Robot(country, company) {
this.country = country;
this.company = company;
}
robot1 = {};
robot2 = {};
// arguments
Robot.apply(robot1, ['Germany', 'KUKA']);
Robot.call(robot2, 'Japan', 'Yaskawa');
console.log(robot1.country, robot1.company); // Germany KUKA
console.log(robot2.country, robot2.company); // Japan Yaskawa
* apply와 call 메소드는 this를 바인딩한 뒤 바로 함수호출
* bind 메소드는 this를 바인딩한 함수를 반환값으로 전달
5. DOM 요소 객체의 이벤트 핸들러
요소 객체 이벤트 핸들러의 this는 요소 객체 자기자신과 바인딩 된다.
* 이벤트 핸들러 내의 일반함수 호출시, 해당함수 내의 this는 window를 참조한다.
<input type="button" onclick="console.log(this);" value="btn0">
<input type="button" onclick="eHandler(this);" value="btn1">
<input type="button" id="btn2" value="btn2">
<input type="button" id="btn3" value="btn3">
<script>
function eHandler(t) {
console.log(t); // input element
console.log(this); // window
}
btn2.onclick = function (e) {
console.log(this); // input element
}
btn3.onclick = function (e) { // output is same as btn1
eHandler(this);
}
</script>
'JavaScript' 카테고리의 다른 글
[JS] 문장과 표현식 (0) | 2020.01.03 |
---|---|
[JS] 프로토타입 (0) | 2020.01.01 |
[JS] 함수 (0) | 2019.12.30 |
[JS] 객체 (0) | 2019.12.30 |
[JS] 연산자 (0) | 2019.12.25 |