🌼 This 와 바인딩
1️⃣ This binding
Object를 참조하는 keyword
javascript는 함수 호출 방식에 따라 '동적'으로 결정 된다.
2️⃣ 함수가 호출되는 방식
🐶 함수 호출시
함수를 호출하면 해당 함수 내부 코드에서 사용된 this는 전역객체(window)에 바인딩된다.
함수는 전역객체의 메소드이다. 따라서 메소드 호출시와 동일하게 메소드 객체(winodw)를 this로 갖는다.
🐶 메소드 호출시
객체의 메소드를 호출할 때는 해당 메소드를 호출한 객체로 바인딩된다.
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
};
var song = new Person("song");
song.getName();
Person.prototype.name = "kim";
Person.prototype.getName();
🐶 엄격모드에서의 this
엄격 모드에서 함수 실행시 this는 undefined가 된다.
내부 함수 호출시 this 또한 undefined가 된다.
의도치 않게 전역객체에 바인딩된 this를 사용하는 것을 막을 수 있다.
🐶 이벤트 리스너 호출시 this
객체의 메서드를 이벤트리스너로 등록했을 때에 this는 이벤트 객체이다.
#("btn").click(function(){
console.log(this);
})
객체로부터 메소드가 분리되었을 때 this는 메소드가 정의된 객체가 아니다.
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return console.log(this.name);
};
var song = new Person("song");
song.getName();
setTimeout(song.getName, 1000);
매개변수로 전달되었기 때문에 메소드는 객체로 부터 분리되어 있고, 함수로써 실행이 된다.
메서드가 정의된 객체를 this로 바인딩하기 위해서는 apply, call, bind를 사용해야한다.
🐶 생성자 함수 호출시 this
자바스크립트 생성자 함수는 객체를 생성한다. 가존 함수에 new를 붙여서 호출하면 생성자 함수로 동작한다.
⓵ 빈 객체 생성 및 this 바인딩
빈 객체 -> 생성된 객체는 this로 바인딩 -> 생성자 함수 코트 내부 this는 빈 객체 -> 이 빈객체가 생성자 함수가 새로 생성하는 객체
② this를 통한 프로퍼티 설정
생성된 빈 객체에 this를 사용해 동적 프로퍼티, 메소드를 생성할 수 있다.
③ 생성된 객체 리턴
정의된 return문이 없다면 새로 생성된 객체가 return
다른 객체를 return하게 했다면 다른 객체가 return
객체가 아닌 값을 return 하는 경우, this로 바인딩된 새 객체가 리턴
var Person = function(name) {
this.name = name;
};
var song = new Person("song");
console.log(song.name);
new를 쓰지 않고 객체를 생성하려할 때, 전역객체에 프로퍼티가 할당되는 등 문제가 생길 수 있다. 그러함으로, new를 통해 생성하도록 강제해준다.
var Person = function(name) {
if (!(this instanceof arguments.callee)) {
return new arguments.callee(arg);
}
this.name = name;
};
🐶 Arrow 함수 호출시 this
- Arrow함수를 선언할 때 this에 바인딩될 객체가
정적
으로 결정된다.
Arrow 함수의 this는 언제나 상위 스코프의 this를 가리킨다.
③ 객체의 메소드를 Arrow 함수로 정의하는 경우
상위 스코프의 this인 전역객체가 this가 된다.
const song = {
name: "song",
sayHi() {
console.log(`Hi ${this.name}`);
}
};
song.sayHi();
song.sayHi();
call, apply, bind를 이용한 this 바인딩
⓵ call
fun.call(thisArg[, arg1[, arg2[, …]]])
- thisArg : 지정할 this
- arg1 … : 객체를 위한 인수
function greet() {
var reply = [this.animal, "typically sleep between", this.sleepDuration].join(" ");
console.log(reply);
}
var obj = {
animal: "cats",
sleepDuration: "12 and 16 hours"
};
greet.call(obj);
② apply
function.apply(thisArg, [argsArray])
- thisArg : 지정할 this
- argsArray : 유사배열 객체(arguments)
- apply가 두 번째 인자를 배열로 넘긴다는 차이가 있다.
③ bind
bind를 사용하면 this 값을 영구히 바꿀 수 있다.
function greet() {
console.log(`Hello, I'm ${this.name}`);
}
greet();
const songGreeting = greet.bind({ name: "song" });
songGreeting();