

그렇다.
내가 쓰는 this는 대부분 내가 생각하는 그것이 아니었다.
js의 this는 함수 호출방식에 따라 결정된다.
js의 함수는 호출될 때, 매개변수로 전달되는 인자값 외에 arguments 객체와 this를 암묵적으로 전달받는다.
실행중에는 할당으로 설정할 수 없고, 함수를 호출할 때마다 다를 수 있다.
아래 링크를 참고하여 글을 쓴다.
this | PoiemaWeb
자바스크립트의 this keyword는 Java와 같은 익숙한 언어의 개념과 달라 개발자에게 혼란을 준다. Java에서의 this는 인스턴스 자신(self)을 가리키는 참조변수이다. this가 객체 자신에 대한 참조 값을
poiemaweb.com
그래서 ES5는 함수가 어떻게 호출되었는지에 상관없이 this값을 설정할 수 있는 bind메서드를 도입했고, this바인딩을 제공하지 않는 애로우 펑션을 추가했다.
함수 호출 방식
1. 함수 호출
const f=function(){
console.log(this);
}
f();
이러면 여기서의 this는 전역객체를 가리킨다.

전역객체는 브라우저에서는 window를, node.js에서는 global객체를 의미한다.
이는 내부함수에서도 마찬가지이다.
function f(){
console.log("f this",this);
function c(){
console.log("c this",this);
}
c();
}
f();

메소드의 내부함수도 마찬가지다
const obj={
value:10,
f:function(){
console.log("f this: ",this);
console.log("f this.valie:",this.value);
function c(){
console.log("c this:",this);
console.log("c this.value:",this);
}
c();
}
}
obj.f();

2. 메소드 호출
함수가 객체의 프로퍼티 값이면, 메소드로써 호출된다.
여기서 this는 해당 메소드를 가진 객체에 바인딩된다.
var obj1 = {
name: 'Lee',
sayName: function() {
console.log(this.name);
}
}
var obj2 = {
name: 'Kim'
}
obj2.sayName = obj1.sayName;
obj1.sayName();
obj2.sayName();

명시적 바인딩(apply, call)
this를 특정 객체에 명시적으로 바인딩 하는 방법이 있으니 그것이 바로 Function.prototype.apply와 FUnction.prototype.call메소드이다.
apply
아래와 같은 형식으로 사용한다.
func.apply(this에바인딩할객체, [함수에, 전달할, 인자들의, 배열, 형태]);
const Person=function(name){
this.name=name;
}
const foo={};
Person.apply(foo,['이름입니다']);
console.log(foo);

이렇게 사용할 수도 있다.

call
call은 apply와 모두 같으나 this에 바인딩할 객체 이후에 배열 대신 하나씩 받는다.
object.apply(foo,[1,2,3]);
object.call(foo,1,2,3);
bind
function Person(name) {
this.name = name;
}
Person.prototype.doSomething = function(callback) {
if(typeof callback == 'function') {
// --------- 1
callback();
}
};
function foo() {
console.log(this.name); // --------- 2
}
var p = new Person('Lee');
p.doSomething(foo); // undefined
1의 관점에서 this는 Person이다. 그러나 2는 Person 외부에 있으므로 this가 window를 가리키게되고, 이 둘의 this가 다르기때문에 문제가 발생한다. 따라서 콜백함수의 this를 호출하는 함수의 this와 일치시켜주어야 하는 번거로움이 발생한다.
call로 해결하기
function Person(name) {
this.name = name;
}
Person.prototype.doSomething = function (callback) {
if (typeof callback == 'function') {
callback.call(this);
}
};
function foo() {
console.log(this.name);
}
var p = new Person('Lee');
p.doSomething(foo); // 'Lee'
callback.call(this)를 통해 this를 바인딩해주었다.
bind를 사용하기
function Person(name) {
this.name = name;
}
Person.prototype.doSomething = function (callback) {
if (typeof callback == 'function') {
// callback.call(this);
// this가 바인딩된 새로운 함수를 호출
callback.bind(this)();
}
};
function foo() {
console.log('#', this.name);
}
var p = new Person('Lee');
p.doSomething(foo); // 'Lee'
함수명.bind(this)와 같이 사용하여 this를 바인딩한다.


그렇다.
내가 쓰는 this는 대부분 내가 생각하는 그것이 아니었다.
js의 this는 함수 호출방식에 따라 결정된다.
js의 함수는 호출될 때, 매개변수로 전달되는 인자값 외에 arguments 객체와 this를 암묵적으로 전달받는다.
실행중에는 할당으로 설정할 수 없고, 함수를 호출할 때마다 다를 수 있다.
아래 링크를 참고하여 글을 쓴다.
this | PoiemaWeb
자바스크립트의 this keyword는 Java와 같은 익숙한 언어의 개념과 달라 개발자에게 혼란을 준다. Java에서의 this는 인스턴스 자신(self)을 가리키는 참조변수이다. this가 객체 자신에 대한 참조 값을
poiemaweb.com
그래서 ES5는 함수가 어떻게 호출되었는지에 상관없이 this값을 설정할 수 있는 bind메서드를 도입했고, this바인딩을 제공하지 않는 애로우 펑션을 추가했다.
함수 호출 방식
1. 함수 호출
const f=function(){
console.log(this);
}
f();
이러면 여기서의 this는 전역객체를 가리킨다.

전역객체는 브라우저에서는 window를, node.js에서는 global객체를 의미한다.
이는 내부함수에서도 마찬가지이다.
function f(){
console.log("f this",this);
function c(){
console.log("c this",this);
}
c();
}
f();

메소드의 내부함수도 마찬가지다
const obj={
value:10,
f:function(){
console.log("f this: ",this);
console.log("f this.valie:",this.value);
function c(){
console.log("c this:",this);
console.log("c this.value:",this);
}
c();
}
}
obj.f();

2. 메소드 호출
함수가 객체의 프로퍼티 값이면, 메소드로써 호출된다.
여기서 this는 해당 메소드를 가진 객체에 바인딩된다.
var obj1 = {
name: 'Lee',
sayName: function() {
console.log(this.name);
}
}
var obj2 = {
name: 'Kim'
}
obj2.sayName = obj1.sayName;
obj1.sayName();
obj2.sayName();

명시적 바인딩(apply, call)
this를 특정 객체에 명시적으로 바인딩 하는 방법이 있으니 그것이 바로 Function.prototype.apply와 FUnction.prototype.call메소드이다.
apply
아래와 같은 형식으로 사용한다.
func.apply(this에바인딩할객체, [함수에, 전달할, 인자들의, 배열, 형태]);
const Person=function(name){
this.name=name;
}
const foo={};
Person.apply(foo,['이름입니다']);
console.log(foo);

이렇게 사용할 수도 있다.

call
call은 apply와 모두 같으나 this에 바인딩할 객체 이후에 배열 대신 하나씩 받는다.
object.apply(foo,[1,2,3]);
object.call(foo,1,2,3);
bind
function Person(name) {
this.name = name;
}
Person.prototype.doSomething = function(callback) {
if(typeof callback == 'function') {
// --------- 1
callback();
}
};
function foo() {
console.log(this.name); // --------- 2
}
var p = new Person('Lee');
p.doSomething(foo); // undefined
1의 관점에서 this는 Person이다. 그러나 2는 Person 외부에 있으므로 this가 window를 가리키게되고, 이 둘의 this가 다르기때문에 문제가 발생한다. 따라서 콜백함수의 this를 호출하는 함수의 this와 일치시켜주어야 하는 번거로움이 발생한다.
call로 해결하기
function Person(name) {
this.name = name;
}
Person.prototype.doSomething = function (callback) {
if (typeof callback == 'function') {
callback.call(this);
}
};
function foo() {
console.log(this.name);
}
var p = new Person('Lee');
p.doSomething(foo); // 'Lee'
callback.call(this)를 통해 this를 바인딩해주었다.
bind를 사용하기
function Person(name) {
this.name = name;
}
Person.prototype.doSomething = function (callback) {
if (typeof callback == 'function') {
// callback.call(this);
// this가 바인딩된 새로운 함수를 호출
callback.bind(this)();
}
};
function foo() {
console.log('#', this.name);
}
var p = new Person('Lee');
p.doSomething(foo); // 'Lee'
함수명.bind(this)와 같이 사용하여 this를 바인딩한다.