java에서는 this가 인스턴스 자신을 가르키지만 자바스크립트에서는 this가 함수가 호출되는 방식에 따라 그 값이 달라진다.
console.log(this) // window or {}
2가지 환경에 따라 전역 this값이 다르다
브라우저 환경이라면 this는 window 객체를 가르킨다.
하지만 Node.js 환경이라면 this는 빈 객체 {} 를 가르킨다.
function foo() {
console.log(this); // window or {}
}
foo();
일반 함수 역시 this는 전역 객체를 가르킨다.
브라우저 환경은 window, Node.js 환경에서는 {}
const obj = {
name: "jon",
printName() {
console.log(this.name);
}
}
obj.printName(); // jon
객체 내부의 메소드로 함수가 호출될 때 해당 메소드를 소유하고 있는 객체를 가르킨다. this는 호출한 객체 obj를 가르키며 this.name은 obj의 name 속성을 가르키는 것과 같다.
function Person(name) {
this.name = name;
}
const john = new Person('John');
console.log(john.name); // 'John'
생성자 함수과 함께 사용된 경우, 새롭게 생성된 인스턴스를 가르키게 된다.
const foo = () => {
console.log(this); // window
}
foo();
화살표 함수일 경우 일반적인 함수 호출과 다르다. 화살표 함수 호출은 자기 자신의 this를 갖고 있지 않다. 화살표 함수의 this는 자기 자신이 아닌 상위 스코프의 this를 가르키게 된다. 위 예제에서는 foo의 스코프가 아닌 전역 스코프의 this 즉 window를 가르키게 된다.
call(), apply(), binde()는 자바스크립트에서 함수의 this를 바인딩 하여 this 값을 원하는 객체로 제어할 수 있도록 제공하는 함수이다.
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
const user = { name: 'John' };
greet("Hello") // Hello
greet.call(user, 'Hello'); // Hello, John
call 없이 일반적으로 호출 하면 당연히 this는 전역 객체인 window를 가르킨다.
하지만 call로 첫 번째 인자를 줄때 this를 가르킬 객체를 전달하면 함수 내부에서는 this가 호출할때 넘긴 user 객체를 가르키게 된다.
function greet(greeting1, greeting2) {
console.log(`${greeting1}, ${this.name}`);
console.log(`${greeting2}, ${this.name}`)
}
const user = { name: 'John' };
greet("Hello") // Hello
greet.apply(user, ['Hello', 'Hi']); // (Hello, John) (Hi, John)
apply()도 call()과 같이 this 객체를 변경시킬 수 있다. 하지만 다른 점은 모든 인자들을 배열 형태로 전달해야하는 점이 다르다. 함수 내부에서는 배열의 개수많큼 변수를 받아 사용하면 된다.
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
const user = { name: 'John' };
const boundGreet = greet.bind(user);
boundGreet('Hello'); // Hello, John
bind()는 함수를 호출하지 않고 새로운 함수를 반환한다. 이 반환된 새로운 함수의 this 값은 bind()에 전달된 첫 번째 인자를 가르킨다.