JS(5) - this

soo's·2023년 4월 7일
0

TIL

목록 보기
31/53
post-thumbnail

📌 this는 그때 그때 다르다.

실행 컨텍스트는 실행할 코드에 제공할 환경정보를 담아놓은 객체라고 했다.
그 안에는 VE와 LE 그리고 this bindings가 있다.
this는 쉽게 말해서 함수를 호출할 때 결정된다.

1. 전역 공간의 this는 전역 객체

전역 공간에서 this를 호출하면 브라우저 환경에서는 window 객체를 가리키고, node 환경에서는 global 객체를 가리킨다.

2. 함수와 메서드의 this는...

먼저 함수와 메서드를 혼용하지 말자.
그 기준은 독립성으로, 함수는 호출의 주체가 없어도 독립적인 기능이 가능하지만 메서드는 호출의 주체가 필요하다.

따라서 함수의 this는 전역 객체를 가리키고
메서드의 this는 호출의 주체를 가리킨다.


// 함수의 this
var func = function (x) {
console.log(this, x); };
func(1); // Window { ... } 

// 메서드의 this
var obj = {
	method: function (x) { console.log(this, x) }
};
obj.method(1); // { method: f } 

위와 같이 브라우저 환경에서 함수의 this는 전역객체인 window를 바인딩하고, 메서드의 경우 자신을 호출한 주체인 객체(obj)를 바인딩한다.

3. 화살표 함수의 this

화살표 함수는 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 없다.
따라서 this는 이전의 값이 유지된다.


var obj = {
outer: function() {
	console.log(this); // (1) obj 
    var innerFunc = () => {
		console.log(this); // (2) obj 
    };
	innerFunc(); 
    }
} 
obj.outer();

위와 같은 코드에서 확인할 수 있듯이, 화살표 함수 속에서 this를 출력해보면 outer 함수에서 바인딩 됐던 this의 값이 유지된다.
따라서 함수와 화살표 함수의 가장 큰 차이점이 무엇이냐고 묻는다면 this 바인딩이라고 답하면 됨

3. 생성자 함수의 this

생성자는 인스턴스를 만들기 위한 틀로, 붕어빵(인스턴스)을 만드는 붕어빵 틀(생성자) 같은거다.


var Cat = function (name, age) { this.bark = ' ';
this.name = name;
this.age = age;
};
var choco = new Cat('초코', 7) // this : choco ; 
var nabi = new Cat('나비', 5); // this : nabi

위와 같이 생성자 함수에서의 this는 생성자(틀)로 만들어진 인스턴스(구체적인 내용물)를 가리킨다. 여기서는 choco와 nabi이다.


명시적 this 바인딩

this를 명시적으로 바인딩해주는 메서드가 몇 가지 있다.

1. call()


var func = function (a, b, c) {
	console.log(this, a, b, c)
}
func.call({x : 1}, 1, 2, 3}); // {x : 1} 1 2 3

call을 사용하지 않으면 위 함수에서 this는 전역 객체인데, call 메서드를 사용해서 this를 명시적으로 {x : 1}이라는 객체로 바인딩 해준 것이다.
함수 뿐만 아니라 호출 주체가 있는 객체의 메서드일 때도 마찬가지로 call을 통해 설정한 객체로 바인딩 해줄 수 있다.
call은 함수를 즉시 실행한다.


2. apply()

var obj = {
	 a: 1,
     method : function (x, y) {
     	console.log(this.a, x, y);
     }
};
obj.method.call({a : 4}, [5, 6]); // 4 5 6

이런식으로 call과 똑같이 함수 즉시 실행, 명시적으로 객체 바인딩 할 수 있음 매개변수 넘겨주는것만 [] 담아서 보내면 됨 ㅇㅇ
그런데 이 apply, call의 개꿀 기능은 바로...
객체에 배열 메서드 적용할 수 있게 해줌

객체에 apply 써서 배열 메서드사용가능
사실 입니다.

예를 들어 객체에는 push라는 배열 메서드 못 쓰잖슴? 그렇지만 call,apply 사용하면 유사배열객체(length가 존재하는 거)에 차용할 수 있음

var obj = {
	0 : '일',
    1 : '이',
    2 : '삼',
    length : 3
}
Array.prototype.push.call(obj, 'd');
console.log(obj); // {0: '일', 1: '이', 2: '삼', 3: 'd', length: 4}

핵심은 저기서 length 빠지면 제 기능 안 함 ㅇㅇ
무조건 객체 -> length 프로퍼티 부여해서 유사배열 객체로 인식해줘야
Array.prototype.push.call(객체, 매개변수, ..) 사용 가능해짐

근데 걍 Array.from(obj)해서 사용해도 될듯. . ^^. .

0개의 댓글