본문 바로가기
javascript

[자바스크립트] this 바인딩

by jinbro 2017. 3. 31.

[this란]
- 자바에서의 this는 객체 자신을 가리킴, 매개변수명과 객체가 가진 멤버변수명이 같을 때 구분하기위한 용도로 사용됨
1
2
3
4
5
6
7
public class Person{
     private String name;
 
     Person(String name){
          this.name = name; //전자는 클래스의 name이고, 후자는 매개변수의 name
     }
}
cs

- 자바스크립트의 this는 함수 호출 패턴에 따라 this가 어떤 객체의 this가 될지 정해짐(어디에 바인딩될지 정해짐)


[함수호출과 this]
1) 함수가 객체의 속성이고, 객체를 통해 함수를 호출할 때 : 객체 각각의 속성을 가리키게됨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var obj1 = {
     name"jinbro",
     sayname: function(){
          console.log(this.name)
     }
}
 
var obj2 = {
     name"park"
}
 
obj2.sayname = obj1.sayname
 
console.log(obj1.sayname()) // "jinbro"
console.log(obj2.sayname()) // "park"
cs

- 프로토타입 객체(자바스크립트 객체지향)에 함수를 정의해두었을 때도 this 바인딩되는 곳이 같음


2) 일반적으로 정의한 함수(전역함수)를 호출할  때 : 전역객체(window)의 변수에 바인딩됨, 똑같은 이름의 변수가 함수 내에 있더라도....
1
2
3
4
5
6
7
8
9
10
var global = "a"
 
function myFunction(){
     var global = "b"
 
     console.log(this.global) // "a"
     console.log(this) // 브라우져의 전역객체인 window가 콘솔에 찍힘
}
 
myFunction() 
cs

- 전역객체(glbal object)는 모든 객체의 유일한 최상위객체, 브라우저에서는 window / node 서버(js)에서는 global을 의미함
- 내부 함수도 this가 전역객체(window)의 속성으로 바인딩됨 === 1번과 같은 것이라 생각하면 됨
=> 객체의 속성에 바인딩되는데, 전역객체가 window고 window의 속성에 전역변수, 함수가 들어가는 것임


3) 생성자함수 호출할 때(생성자함수를 가지고 객체를 생성할 때 매개변수로 값을 넘겨주고 this로 바인딩) : 각 매개변수값이 바인딩됨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var Person = function(name){
    if(name.length == 0){
        this.name = Person.prototype.name
    } else{
        this.name = name
    }
}
 
Person.prototype.name = "이름없음"
 
var jinbro = new Person("jinbro")
var mumu = new Person("")
 
console.log(jinbro.name// "jinbro"
console.log(park.name// "이름없음"
cs

- 바인딩 매커니즘
(1) new 키워드를 사용하면 생성자함수 코드가 실행되기 전 빈 객체가 생성됨
(2) 빈 객체는 생성자함수가 새로 생성하는 객체이며, this에 객체가 바인딩됨
(3) 생성된 빈 객체는 생성자함수의 프로토타입 객체를 자신의 프로토타입 객체로 설정

- 정리
(1) 생성자함수 내 this는 생성자함수를 통해 생성된 객체를 뜻함
(2) 객체의 프로토타입은 생성자함수의 프로토타입객체

- 자바처럼 클래스 내 생성자함수가 따로 존재하지않고, 함수가 객체이자 new 키워드를 붙이면 생성자함수 역할을 함
=> 일반함수와 생성자함수를 구분하기위해 생성자함수명의 첫글자는 대문자로 지정하자

- 생성자함수로 사용할 것임에도 불구하고 new 키워드를 붙이지않을 경우 일반함수 호출이기 때문에 방식이 달라 undefined 상태에 빠짐
=> this가 전역객체(window)의 변수를 가리키기때문에 전역변수의 값은 변경됨
=> 제대로 하면 생성자함수의 객체(new 키워드) 생성 할 때에는 this가 새롭게 생성된 객체에 바인딩되기때문에 새로 생성된 객체의 속성 생성 및 변경됨



4) 자바스크립트 엔진 내부 매커니즘이 아닌 임의적으로 특정 객체에 바인딩 시키는 방법 : Function(모든 함수의 객체)의 프로토타입 객체의 apply(), call() 메서드


- 함수(객체)의 함수를 호출하여 this에 특정 객체를 바인딩시킴

(1) apply 메서드
1
2
3
4
5
6
7
8
9
var Person = function(name){
     this.name = name
}
 
var obj1 = {}
 
Person.apply(obj1, ['jinbro'])
 
console.log(obj1) // Object { name: "jinbro" }
cs

- 첫번째 매개변수로 빈 객체(this 바인딩 객체), 두번째 매개변수로 매개변수값 
- 내부적으로는 빈객체 생성 후 빈객체가 this에 바인딩되고, 빈객체에는 name 프로퍼티가 없기때문에 생성 후 값을 할당함

(2) call 메서드
1
2
3
4
5
6
7
8
9
10
var Person = function(name, gender){
     this.name = name
     this.gender = gender
}
 
var jinbro = {}
 
Person.call(jinbro, "jinbro""male")
 
console.log(jinbro)
cs

- apply 메서드와 기능은 같으나, 매개변수에서 차이가 있음
- 첫번째 매개변수는 바인딩할 객체, 두번째 매개변수부터는 매개변수값(배열형태가 아닌 하나씩 넘김)



[this 결론]
- 자바를 생각하고 this를 사용하면 안됨, 자바스크립트 this는 사용방식에 따라 바인딩되는 것이 다름
- 내부 매커니즘을 잘알고 this 잘 사용하자







'javascript' 카테고리의 다른 글

[자바스크립트] 실행컨텍스트: js 동작원리  (0) 2017.04.08
[웹 기본개념] 세션  (0) 2017.04.05
[웹 기본개념] 쿠키  (0) 2017.03.28
[웹 기본개념] URL / URI / REST API  (0) 2017.03.24
[자바스크립트] scope  (0) 2017.03.21

댓글