const circle = {
radius: 5,
getDiameter() {
return this.radius * 2;
}
};
console.log(circle.getDiameter()); / 10
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.getDiameter = function () {
return this.radius * 2;
};
const circle = new Circle(5);
console.log(circle.getDiameter()); // 10
// 전역에서 this는 전역 객체 window를 가리킨다.
console.log(this); // window
function square(number) {
// 일반 함수 내부에서 this는 전역 객체 window를 가리킨다.
console.log(this); // window
return number * number;
}
square(2);
const person = {
name: 'Lee',
getName() {
// 메서드 내부에서 this는 메서드를 호출한 객체를 가리킨다.
console.log(this); // {name: 'Lee', getName: f}
return this.name;
}
};
console.log(person.getName()); // Lee
function Person(name) {
this.name = name;
// 생성자 함수 내부에서 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
console.log(this); // Person {name: 'Lee'}
}
const me = new Person('Lee');
렉시컬 스코프는 함수 정의가 평가되어 함수 객체가 생성되는 시점에 상위 스코프 결정.
this 바인딩은 함소 호출 시점에 결정.
function foo() {
console.log(this); // window
function bar() {
console.log(this); // window
}
bar();
}
foo();
function foo() {
'use strict';
console.log(this); // undefined
function bar() {
console.log(this); // undefined
}
bar();
}
foo();
var value = 1;
const obj = {
value: 100,
foo() {
console.log(this); // {value: 100, foo: f}
console.log(this.value); // 100
function bar() {
console.log(this); // window
console.log(this.value); // 1
}
bar();
}
}
obj.foo();
var value = 1;
const obj = {
value: 100,
foo() {
console.log(this); // {value: 100, foo: f}
console.log(this.value); // 100
setTimeout(function(){
console.log(this); // window
console.log(this.value); // 1
}, 100);
}
}
obj.foo();
// 1. 변수에 this 할당
var value = 1;
const obj = {
value: 100,
foo() {
// 변수에 this 바인딩 할당.
const that = this;
// 콜백 함수 내부에서 변수 that 참조
setTimeout(function(){
console.log(that.value); // 100
}, 100);
}
}
obj.foo();
// 2. Function.prototype.bind 메서드 활용
const obj2 = {
value: 100,
foo() {
// 콜백 함수에 명시적으로 this 바인딩
setTimeout(function(){
console.log(that.value); // 100
}.bind(this), 100);
}
}
obj2.foo();
// 3. 화살표 함수 활용
const obj3 = {
value: 100,
foo() {
// 화살표 함수 내부의 this는 사우이 스코프의 this를 가리킨다.
setTimeout(() => {
console.log(that.value); // 100
}, 100);
}
}
obj3.foo();
const person = {
name: 'Lee',
getName() {
// 메서드 내부의 this는 메서드를 호출한 객체에 바인딩된다.
return this.name;
}
};
// 메서드 getName을 호출한 객체는 person이다.
console.log(person.getName()); // Lee
const anotherPerson = {
name: 'Kim'
};
// getName 메서드를 anotherPerson 객체의 메서드로 할당
anotherPerson.getName = person.getName;
// getName 메서드를 호출한 객체는 anotherPerson.
console.log(anotherPerson.getName()); // Kim
// getName 메서드 변수에 할당
const getName = person.getName;
// getName 메서드를 일반 함수로 호출 -> this.name === window.name
console.log(getName()); // ''
function Person(name) {
this.name = name;
}
Person.prototype.getName = function(){
return this.name;
};
const me = new Person('Lee');
// getName 메서드를 호출한 객체는 me
console.log(me.getName()); // Lee
Person.prototype.name = 'Kim';
// getName 메서드를 호출한 객체는 Person.prototype
console.log(Person.prototype.getName()); // Kim
function Circle(radius) {
this.radius = radius;
this.getDiameter = function() {
return this.radius * 2;
};
}
const circle1 = new Circle(5);
const circle2 = new Circle(10);
console.log(circle1.getDiameter()); // 10
console.log(circle2.getDiameter()); // 20
// Function.prototype.apply(thisArg[, argsArray]);
// Function.prototype.call(thisArg[, arg1[, arg2, ...]]);
function getThisBinding() {
console.log(arguments);
return this;
}
const thisArg = { a: 1 };
// apply 메서드는 함수의 인수를 <배열>로 묶어 전달
console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
// Arguments(3) [1, 2, 3, callee: f, Symbol(Symbol.iterator): f]
// {a: 1}
// call 메서드는 함수의 인수를 <쉼표>로 구분하여 전달
console.log(getThisBinding.call(thisArg, 1, 2, 3));
// Arguments(3) [1, 2, 3, callee: f, Symbol(Symbol.iterator): f]
// {a: 1}
function getThisBinding() {
return this;
}
const thisArg = { a: 1 };
// bind 메서드는 함수에 this로 사용할 객체를 전달한다.
// bind 메서드는 함수를 호출하지 않는다.
console.log(getThisBinding.bind(thisArg)); // getThisBinding
// bind 메서드는 함수를 호출하지는 않으므로 명시적으로 호출해야한다.
console.log(getThisBinding.bind(thisArg)()); // {a: 1}