Javascript this
- 자바스크립트의 함수는 호출될 때, 매개변수로 전달되는 인자값 이외에,
arguments 객체와 this를 암묵적으로 전달 받는다.
1 | function square(number) { |
This는 특별한 상황 2가지를 제외한 경우는 모두 전역변수를 의미한다.- 예외 1. method로 호출될때 호출한 것이 this로 사용된다./ method의 내부함수도 전역 변수이다.
- 예외 2. 생성자 함수에서 생성된 객체의 경우
this는 생성자 함수가 생성할 객체를 가르킨다.
자바스크립트의 경우 자바와 같이 this에 바인딩되는 객체는 한가지가 아니라
해당 함수 호출 패턴에 따라 this에 바인딩되는 객체가 달라진다.
함수 호출 패턴과 this 바인딩
- 메소드 호출 패턴(Method Invocation Pattern)
- 함수 호출 패턴(Function Invocation Pattern)
- 생성자 호출 패턴(Constructor Invocation Pattern)
- apply 호출 패턴(Apply Invocation Pattern)
1. 메소드 호출 패턴(Method Invocation Pattern)
- this는 그 method를 소유한 객체를 가르킨다.
즉 그 method를 호출한 객체를 가르킨다.
1 | var obj1 = { |
- 프로토타입 객체도 메소드를 가질 수 있다. 프로토타입 객체 메소드 내부에서 사용된 this도 일반 메소드 방식과 마찬가지로 해당 메소드를 호출한 객체에 바인딩된다.
즉 함수를 부른 객체에 적용이된다.
Q. obj2에는 sayName함수가없는데 이것은 obj2__proto__, obj1__proto__가 같아서인가요?? 아니면 무슨이유인가요?
A. this의 특징인 method를 호출한 객체를 가르키기 때문이다.
1 | function Person(name) { |

2. 함수 호출 패턴(Function Invocation Pattern)
전역객체(Global Object)는 모든 객체의 유일한 최상위 객체를 의미하며 일반적으로 Browser-side에서는 window, Server-side(Node.js)에서는 global 객체를 의미한다.
기본적으로 this는 전역객체(Global object)에 바인딩된다. 전역함수는 물론이고 심지어 내부함수의 경우도 this는 외부함수가 아닌 전역객체에 바인딩된다.
method 내부의 내부함수의 this도 전역을 가르킨다. (설계상 결점)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var value = 1;
var obj = {
value: 100,
foo: function() {
console.log("foo's this: ", this); // obj
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();콜백함수의 경우에도 this는 전역객체에 바인딩된다.(설계적 결함)
1
2
3
4
5
6
7
8
9
10
11
12
13var value = 1;
var obj = {
value: 100,
foo: function() {
setTimeout(function() {
console.log("callback's this: ", this); // window
console.log("callback's this.value: ", this.value); // 1
}, 100);
}
};
obj.foo();this의 전역객체 회피방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19var value = 1;
var obj = {
value: 100,
foo: function() {
var that = this; // Workaround : this === obj
console.log("foo's this: ", this); // obj
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
console.log("bar's that: ", that); // obj
console.log("bar's that.value: ", that.value); // 100
}
bar();
}
};
var that = this; 여기서 this는 obj이다 즉 that은 obj이므로 이상해지면 that을 써준다.
3. 생성자 호출 패턴(Constructor Invocation Pattern)
- 생성자 함수를 생성시
new를 쓴것과 안쓴것은 차이가 있다.
3.1 생성자 함수 동작 방식
- 빈 객체 생성 및 this 바인딩
- this를 통한 프로퍼티 생성
- 생성된 객체 반환
- 생성자 함수 내부에는 return을 안써주는 것이다. 암묵적으로 해주기에 안써주는것이다 쓰면 코드가 꼬인다.
this는 생성자 함수가 생성할 객체를 가르킨다.
1 | var Person = function(name) { |

3.3 생성자 함수에 new 연산자를 붙이지 않고 호출할 경우
1 | var Person = function(name) { |
- me에다가 값이 들어가지 않고 window에 값이 들어간다.
방어코드를 작성해서 new를 빼먹는 경우를 방어한다.
1 | // Scope-Safe Constructor Pattern |
- argument.callee는 생성자의 이름이 나타난다.
4. apply 호출 패턴(Apply Invocation Pattern)
유사배열 : 유사배열은 배열이아닌 객체라서 배열처럼 불를수있지만
원래의 순서가 보장이 안된다.
- func.apply는 func의 양부인 Function.prototype 객체의 메소드이다.
- []는 option을 나타낸다.
1 | func.apply(thisArg, [argsArray]) |
1 | var Person = function (name) { |
1 | function convertArgsToArray() { |
- argumetns 객체는 배열 객체는 아닌데 slice를 쓰게해달라고 해주는게 apply이다 그래서 배열객체의.prototype에 .apply를 통해서 argument가 쓰게해준다.
1 | Person.apply(foo, [1, 2, 3]); |
- call과 apply의 차이는 배열이냐 , 이냐의 차이이다.
1 | function Person(name) { |
- callback함수에다가 직접적으로 call에 this를 명시해줘서 일반함수가 callback을 사용할 수 있게 해준다.
1 | function Person(name) { |