객체
this
function foo() {
console.log("foo's this: ", this); // window
function bar() {
console.log("bar's this: ", this); // window
}
bar();
}
foo();
// stict mode의 경우
function foo() {
'use strict';
console.log("foo's this: ", this); // undefined
function bar() {
console.log("bar's this: ", this); // undefined
}
bar();
}
foo();
// 중첩 함수를 일반 함수로 호출할 경우
var value = 1;
const obj = {
value: 100,
// 메서드
foo() {
console.log("foo's this: ", this); // {value: 100, foo: f}
console.log("foo's this.value: ", this.value); // 100
// 중첩 함수
function bar() {
console.log("bar's this: ", this); // window
console.log("bar's this.value: ", this.value); // 1
}
// 일반 함수 호출
bar();
}
};
// 메서드 호출
obj.foo();
// 콜백 함수를 일반 함수로 호출할 경우
var value = 1;
const obj = {
value: 100,
// 메서드
foo() {
console.log("foo's this: ", this); // {value: 100, foo: f};
// 콜백 함수를 일반 함수로 호출함
setTimeout(function() {
console.log("callback's this: ", this); // window
console.log("callback's this.value: ", this.value); // 1
}, 100);
}
}
obj.foo();
// 외부 함수의 지역 변수 that에 this를 할당함
var value = 1;
const obj = {
value: 100,
foo() {
const that = this; // {value: 100, foo: f}
setTimeout(function() {
console.log(that.value); // 100
}, 100);
}
}
obj.foo();
// bind 메서드를 사용하여 this를 명시적으로 바인딩함
var value = 1;
const obj = {
value: 100,
foo() {
setTimeout(function() {
console.log(this.value); // 100
}.bind(this), 100);
}
}
obj.foo();
// 화살표 함수를 사용하여 상위 스코프의 this를 가리키게 함
var value = 1;
const obj = {
value: 100,
foo() {
setTimeout(() => {
console.log(this.value); // 100
}, 100);
}
}
obj.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
// 메서드를 변수에 할당하여 일반 함수로 호출할 수 있음
const getName = person.getName;
// 일반 함수로 호출할 경우 함수 내부의 this : 전역객체 window
console.log(getName()); // '' (window.name)
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 : 생성자 함수가 생성할 인스턴스(객체)
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
return this;
}
// 반지름이 5인 Circle 객체를 생성함
const circle1 = new Circle(5);
// 반지름이 10인 Circle 객체를 생성함
const circle2 = new Circle(10);
console.log(circle1.getDiameter()); // 10
console.log(circle2.getDiameter()); // 20
// new 연산자 없이 함수를 호출하면 일반 함수로 동작함
const circle3 = Circle(15);
// 일반 함수로 호출할 경우 this : 전역 객체
console.log(circle3); // window
console.log(radius); // 15
apply, call, bind 메서드
apply, call 메서드
// 사용법
Function.prototype.apply(thisArg, [, argsArray])
Function.prototype.call(thisArg, [, arg1, [, arg2, ...]])
// 예시
function getThisBinding() {
return this;
}
// this로 사용할 객체
const thisArg = { a: 1 };
console.log(getThisBinding().apply(thisArg), [1, 2, 3]); // { a: 1 }
console.log(getThisBinding().call(thisArg), 1, 2, 3); // { a: 1 }
function convertToArray() {
// arguments 객체를 배열로 변환함
const arr = Array.prototype.slice.call(arguments);
// const arr = Array.prototype.slice.call(arguments);
console.log(arr); // [1, 2, 3]
}
convertToArray(1, 2, 3);
// 사용법
Function.prototype.bind(thisArg, [arg1], [arg2], ...)
// 예시
function getThisBinding() {
return this;
}
// this로 사용할 객체
const thisArg = { a: 1 };
// thisArg로 this 바인딩이 교체된 getThisBinding을 생성하여 반환함
console.log(getThisBinding().bind(thisArg)); // getThisBinding
// bind 메서드는 함수를 호출하지 않으므로 함수를 명시적으로 호출해야함
console.log(getThisBinding().bind(thisArg)()); // { a: 1 }
const person = {
name: 'Lee',
foo(callback) {
// bind 메서드로 callback 함수 내부의 this 바인딩을 전달
setTimeout(callback.bind(this), 100);
}
}
person.foo(function () {
console.log(`My name is ${this.name}`); // My name is Lee
});
for (let key in user) {
if (typeof user[key] == 'function') {
user[key] = user[key].bind(user);
}
}
function multiply(a, b) {
return a * b;
}
let double = multiply.bind(null, 2);
console.log(double(3)); // = mul(2, 3) = 6
console.log(double(4)); // = mul(2, 4) = 6
console.log(double(5)); // = mul(2, 5) = 6
function foo() {
console.log(this.name); // John
}
const f = foo.bind({name: "John"}).bind({name: "Ann"});
f();
함수 호출 방식 | this 바인딩 |
---|---|
일반 함수 호출 | 전역 객체 |
메서드 호출 | 메서드를 호출한 객체 |
생성자 함수 호출 | 생성자 함수가 생성할 인스턴스 |
Function.prototype.apply/call/bind 메서드에 의한 간접 호출 | Function.prototype.apply/call/bind 메서드에 첫 번째 인수로 전달한 객체 |