[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 |
댓글