👉 함수를 호출하는 방식에 따라
this
에 바인딩할 객체가 동적으로 결정된다.
// 브라우저
this === window // true
// 서버 (node.js)
this === global // true
var first = 'spring'
console.log(this.first) // spring
function favouriteWeather() {
this.second = 'summer';
console.log(this); // window
}
console.log(this.second); // undefined
this.third = 'fall';
console.log(this.third); // fall
console.log(this.second); // undefined
favouriteWeather();
console.log(this.third); // fall
console.log(this.second); // summer
this
는 전역 객체(window
)를 컨텍스트 객체로 갖는다.👉 객체의 value 값으로 담긴 함수를 메소드라고 한다.
var b = 200;
function func0() {
console.log(this.b);
}
const obj = {
a: 100,
func1: func0,
func2: function() {
console.log(this.b);
}
};
obj.func1(); // undefined
obj.func2(); // undefined
const func3 = obj.func1;
func3(); // 200
obj.func1()
에서 func1은 객체 obj를 통해 호출되어서 obj는 this의 컨텍스트 객체가 된다. func1을 호출할 경우 func0이 실행되는데 obj에는 b가 할당되어 있지 않기 때문에 undefined가 출력된다.obj === this
가 된다.window.func3
과 같다.func3
에서 this
의 컨텍스트는 다시 전역 객체인 window가 되기 때문에window.func3 === this.func3 === obj.func1
이 된다.
new
키워드를 사용하여 함수를 호출할 경우 만들어진 객체를 인스턴스라고 부른다.
function original(student, time, course) {
this.student = student;
this.time = time;
this.course = course;
}
const fresh1 = new original('john', 'full-time', 'immersive');
console.log(fresh1.student) // 'john'
console.log(fresh1.time) // 'full-time'
console.log(fresh1.course) // 'immersive'
const fresh2 = original('yuno', 'part-time', 'pre');
console.log(fresh2); // undefined
console.log(fresh2.student); // TypeError: fresh2 is not a function
fresh1
)가 만들어지고 호출된 함수(original
)과 연결된다.fresh1
)를 context 객체로 사용하여 함수가 실행된다.new
키워드 없이 호출할 경우 이는 함수 실행으로 판단되는데, 함수 original
에 리턴값이 없기 때문에 undefined
를 출력하게 된다.fresh2.student
는 undefined
에 student
라는 속성으로 접근을 하여 생긴 오류인데, 결국엔 undefined.student
를 한 셈이 되어 오류를 발생시킨다.👉
call
apply
는 함수를 실행,bind
는 함수를 리턴한다.
✔️ 이 세 개의 메서드는 첫 번째 인자를 this
값으로 지정한다.
var age = 23; // global
function func1() {
console.log(this.age);
}
const mark = { age: 21 };
func1(); // 23
func1.call(mark); // 21
func1.apply(mark); // 21
const func2 = func1.bind(mark);
func2(); // 21
this
의 context 객체가 된다.func1
을 호출할 경우, this
는 window
이기 때문에 전역 변수를 불러온다.call
apply
bind
를 사용하여 호출할 경우, 첫 번째 인자가 this
의 context 객체가 되기 때문에, 인자로 들어온 객체가 this
로 바인딩 된다. → this.age === mark.age
call
은 두 번째 인자로는 함수의 매개변수로 전달된다.func.call(this, ...args)
var obj = {};
function personal(name, job) {
this.name = name;
this.job = job;
}
personal.call(obj, 'mark', 'author');
// obj = { name: 'mark', job: 'author' }
call
에서는 두 번째 인자부터 함수의 매개변수에 할당된다. 그러므로 함수 personal
의 첫 번째 매개변수(name)에는 두 번째 인자인 'mark'가, 두 번째 매개변수(job)에는 다음 인자인 'author'가 할당된다.function profile(grade, ...args) {
return `I am year ${grade} ${this.job}, my major is ${args[0]} & ${args[1]}.`;
}
const me = { job: 'student' };
profile.call(me, 13, 'finance', 'accounting');
// 'I am year 13 student, my major is finance & accounting.'
me
는 this
로 바인딩 된다.call
의 두 번째 인자 이후로는 매개변수로 전달되기 때문에 job = student
grade = 13
이 되고, 그 이후의 인자들은 rest parameter(...args
)에 할당된다.apply
는 두 번째 인자를 배열로 받고 배열 속 요소들을 함수의 매개변수에 할당한다.func.apply(this, [...args])
var obj = {};
function personal(name, job) {
this.name = name;
this.job = job;
}
personal.apply(obj, ['mark', 'author']);
// obj = {name: "mark", job: "author"}
this
값과 배열로 제공되는 args
로 함수를 호출한다.function profile(name, country, ...args) {
return `${name} is an ${this.job} from ${country}, and he likes ${args} a lot.`;
}
const him = { job: 'author' };
profile.apply(him, ['mark', 'canada', 'watermelon']);
// 'mark is an author from canada, and he likes watermelon a lot.'
apply
에서는 첫 번째 인자인 him
은 this
로 바인딩 되며, 두 번째 인자는 배열 형태로 전달된다.const numbers = [1, 90, 25, 71, 66];
Math.max(...numbers); // 90
Math.max.call(null, ...numbers); // 90
Math.max.apply(null, numbers); // 90
call
을 사용할 경우, rest parameter를 사용하여 두 번째 인자에 전달해준다.apply
를 사용할 경우, numbers
는 배열이기 때문에 그 자체를 두 번째 인자로 전달해준다.bind
는 새로운 함수를 반환한다.
bind
는 함수를 실행하지 않고,this
context를 담은 함수를 리턴한다. 그러므로bind
메서드를 사용한 후에 한 번 더 호출을 해주어야 함수 안에 있는this
를 원하는 객체로 바인딩 할 수 있다.
var binobj = {};
function personal(name, job) {
this.name = name;
this.job = job;
}
const other = personal.bind(binobj);
other('mark', 'author');
// binobj = {name: "mark", job: "author"}
this
, 두 번째 인자부터는 필요한 매개변수를 전달한다.this
값 객체를 할당해준 뒤, 재호출 시 인자를 추가할 수 있다.function add(num1, num2) {
return num1 + num2;
}
const firstResult = add.bind(null, 10, 20);
firstResult; // 함수 add를 출력
firstResult(); // 30
const secondResult = add.bind(null, 10);
secondResult(20); // 30
typeof secondResult; // function
bind
는 함수를 실행하는 것이 아닌 새로운 함수를 반환하는 메서드이다. 새로 선언된 firstResult
나 secondResult
를 입력할 경우 함수 add
를 출력하게 된다.bind
메서드를 사용한 뒤에 한 번 더 호출을 해주어야 한다.function
키워드를 사용할 경우 ➙ 함수가 어떻게 실행되는지에 따라 결정된다.arrow function
을 사용할 경우 ➙ this
값을 상관하지 않는다. ( = this
바인딩을 하지 않음)👉 그러므로 this
를 사용하기 위해서는 키워드 function
을 반드시 작성해야 한다.
참고한 글